-->

Custom filter in rails ActiveAdmin using ransack

2019-05-18 13:19发布

问题:

I have created an activeadmin filter that has the following choices on filtering the table data in its drop-down menu.

Choice A

Choice B

Choice C

Choice D

I want to add a fifth choice F that would either choice B or C (that is the results of both B and C).

Choice A

Choice B

Choice C

Choice D

Choice F = either B or C

The choices are stored in a table called Coupons in its title field (i created a row having the choice F). So far, I tried to employ a ransack to do the trick, without being quite sure.

//app/admin/user.rb
filter :has_right_choice, label: 'Filter by the right choice', collection: Coupon.all, as: :select

//app/models/user.rb
ransacker :has_right_choice, :formatter => ->(title) {
   if (title == 'Choice F')
      Coupon.all.where("title = 'Choice B' OR title = 'Choice C'")
   else
      Coupon.all
   end

 } do |parent|
 parent.table[:id]
end

But my solution doesn't work. Is there a better approach instead of ransack ? If not, any suggestion ?

========================================================================== EDIT: solution

Choice A # lets say that this choice has id = 1 in Coupons table

Choice B # id = 2

Choice C # id = 3

Choice D # id = 4

Choice F # id = 5

Also lets say that Users table has a field choice_id that refers to the Choices table. We modify the faulty code as follows:

//app/admin/user.rb
filter :choice_id_in, label: 'Filter by the right choice', collection: Coupon.all, as: :select


//app/models/user.rb
  ransacker :choice_id,
            :formatter => -> (coupon_id) {
              if (coupon_id == "5")
                  ids  = User.all.where("choice_id = 3 OR choice_id = 4").map(&:id)
              else
                  ids = User.where("choice_id = ?", coupon_id).map(&:id)
              end
              (ids.empty?) ? ids << 0: ids #activeadmin translates the queries into IN operator, may get syntax error if empty
                    # id = 0 is non-existent in Users as id >= 1
              ids #maybe is not needed
              } do |parent|
  parent.table[:id]
  end

Suggestions for improvement are welcome. Thanks @berker for the guidance.