Reputation: 4797
I run into a problem while trying to filter on a resource on Active Admin.
Filters actually work perfectly when I apply them to standard stuff but here it's a multi-select.
Indeed in my Deals model: There is a "Deal_goal" attribute and I can choose many Deal_goal such as "acquire new users", or "generate buzz"
Here is how I input it on my active admin form:
f.input :deal_goal,
:label => "Deal goals",
:as => :select,
:multiple => true,
:collection => DEAL_GOALS
To make the multi select, I serialize it on my Deal model
app/models/deal.rb
class Deal < ActiveRecord::Base
serialize :deal_goal, Array
I am also using staal.io advice for multi-selects (the 'chosen' gem)
What I fail to do is on my index page (list of deals), to have a filter on my Deal_goal attribute and if possible to have a multi-select here enabling me to filter on deals based on more than one type of goal (for example: filter deals with goal#1 or goal#3)
I tried both of what is below on admin/deal.rb and none worked!
filter :deal_goal, :as => :select, :collection => DEAL_GOALS
filter :deal_goal, :as => :multiple_select, :collection => DEAL_GOALS
Does anybody have a clue?
Upvotes: 1
Views: 5163
Reputation: 3205
You can create a multiple select in the same way you do in your form, with multiple: true
:
filter :deal_goal, as: :select, collection: DEAL_GOALS, multiple: true
Querying PostgreSQL arrays from Active Admin / Ransack can be done, it just takes a bit more work. First off, you should add the postgres_ext gem to your Gemfile. It gives you a nice set of query methods that you can use like this:
User.where.contains roles: ['foo']
# or:
User.where User.arel_table[:roles].contains ['foo']
The next step is to tell Ransack that these query methods (or "predicates") exist. Put this in an initializer:
# https://github.com/activerecord-hackery/ransack/issues/321
Ransack.configure do |config|
{ array_contained_within: :contained_within,
array_contained_within_or_equals: :contained_within_or_equals,
array_contains: :contains,
array_contains_or_equals: :contains_or_equals,
array_overlap: :overlap
}.each do |rp, ap|
config.add_predicate rp, arel_predicate: ap, wants_array: true
end
end
You can confirm that Ransack is picking up on the added methods if this:
User.search(roles_contains: [3,4]).result.to_sql
Generates this SQL:
SELECT "users".* FROM "users" WHERE ("users"."roles" @> '{"3","4"}')
Now to get these new methods working with Active Admin.
ActiveAdmin.register User do
filter :roles_array_contains, as: :select, multiple: true, collection: ['foo', 'bar']
end
Of course, be sure to change User
and roles
to the model and attribute that fits your situation.
One final note. I noticed you're manually setting up serialize :attr, Array
in your model. For your array to be a PostgreSQL array you have to specify array: true
in the database migration. Assuming you've already done that, then this serialize
call is unnecessary. In fact, it seems to break this approach for some reason, so be sure to remove it.
Upvotes: 7