Search code examples
arraysruby-on-rails-4activeadminactivemodelransack

Custom filter in ActiveAdmin using 2 level array


Currently I have a Case model with the filter:

filter :specialty, as: :select, collection: Specialty.order(:category, :name)

The filter dropdown shows this:

category1 - name1
category1 - General
category1 - name2
category2 - name1
category2 - name2
category2 - name3

Under :name there's a string General which I always want to be on top of the list which is sorted alphabetically. So the filter will always show the :category in alphabetical order followed by :name in alphabetical order.

I want this dropdown to show this:

category1 - General
category1 - name1
category1 - name2
category2 - name1
category2 - name2
category2 - name3

I've decided to write a method in the Case model so that I can call it within the AA filter like this:

filter :specialty, as: :select, collection: Specialty.my_method

The my_method currently looks like this:

  def self.my_method
    groups = []

    category_list = Specialty.distinct(:category).pluck(:category, :name)

    category_list.sort_by! do |category, name|
      name == 'General' ? "#{category}, #{''}" : "#{category}, #{name}"
    end

    category_list.each do |category|
      groups << [category, Specialty.where(category: category).order('name')]
    end

    return groups
 end

The problem is that this shows the dropdown as an array instead of strings and it looks like this:

["category1", "General"]
["category1", "name1"]
["category1", "name2"]
["category2", "name1"]
["category2", "name2"]
["category2", "name3"]

How would I modify my code to make it show up correctly? Does ransack have any bearing on this?


Solution

  • It turned out that I was overthinking the query algorithm. Here's the code to make this return the right array.

    def self.my_method
      all.sort_by do |specialty|
        specialty.name == 'General' ? [specialty.category, ''] :
        [specialty.category, specialty.name]
      end
    end
    

    The dropdown now shows:

    category1 - General
    category1 - name1
    category1 - name2
    category2 - name1
    category2 - name2
    category2 - name3