Search code examples
ruby-on-railsancestryadministrate

How do I relate Ancestry gem data in Administrate gem


I'm using the Administrate gem in my Rails 6 application. I have created a category model and I'm using the ancestry gem to organise the tree structure etc. I'm having trouble trying to integrate the ancestry gem into Administrate. Mainly an issue where the parent_id for ancestry gem is null so and 2. trying to display the child name/relationships in Administrate.

  1. The Administrate gem because of the relationship will not accept a null value when editing the form is "ancestry" is added to the dashboard form in administrate.
  2. Another problem I am trying to overcome is displaying the associated name of a child the id that ancestry uses. So ancestry using a string field which helps locate the parent using the id of the category row. I have no idea how to manipulate the Administrate dashboard/controller to display the field name.

Any help would be so much appreciated. I've googled this one for a bit and cannot seem to find anything related to the same problem.

Is it worth using Ancestry and Administrate together? Or should I just create my own category controller and views to allow Admin to modify the category data? I'd prefer to try to keep all admin stuff in Administrate if possible.

Thanks a mil.


Solution

  • Just adding my solution below in case anyone else comes across the question.

    To allow Administrate to accept a null value even though there might be presence required because of the ancestry gem use of the relationship in the model. eg.

    class Category < ApplicationRecord
      has_ancestry
    end
    

    You can override the 'resource params' in the Admin controller in Administrate.

    # Override `resource_params` if you want to transform the submitted
    # data before it's persisted. For example, the following would turn all
    # empty values into nil values. It uses other APIs such as `resource_class`
    # and `dashboard`:
    
     def resource_params
       params.require(resource_class.model_name.param_key).
         permit(dashboard.permitted_attributes).
         transform_values { |value| value == "" ? nil : value }
     end
    

    Part 2.

    In the Dashboard category, I wanted to change the ID to a descriptive name. Ancestry gem uses a string field to show the ID of the Parent Category.

    Dashboards > category_dashboard.rb file

      ATTRIBUTE_TYPES = {
        ancestry: Field::Select.with_options(collection: Category.all.map do |cat| [cat.name, cat.id] end),
        #ancestry: Field::Text,
      }.freeze
    

    I have made the attriubte_type a select with options value instead of text field and mapped the name and id.

    This allowed me to select the ID's of a parent category seeing their names instead of ID's. However, I could not select a Null value and I required to leave this select area blank if I wanted Part 1 to do its thing and make a blank field = null. Making the category a parent category when added by an Admin user.

    You can generate all the fields in Administrate using a generate command. (I'll add this to the comments once I have a chance).

    Once added I could edit the Select field forms. This allowed to me add :include_blank => 'Primary Category' to the select field form in adminstrate.

       <% if field.selectable_options.first&.is_a?(Array) %>
           <%= f.select(
             field.attribute,
             options_from_collection_for_select(
               field.selectable_options,
               :last,
               :first,
               field.data.presence,
             ),
           :include_blank => 'Primary Category'
           ) %>
      <% else %>
        <%= f.select(
          field.attribute,
          options_from_collection_for_select(
            field.selectable_options,
            :to_s,
            :to_s,
            field.data.presence,
          ),
        :include_blank => 'Primary Category'
        ) %>
      <% end %>