在Active Admin上过滤多选(Rails 3.2/postgreSQL/active admin 1.0)

Mat*_*ieu 1 ruby ruby-on-rails ruby-on-rails-3 activeadmin

尝试过滤Active Admin上的资源时遇到问题.

当我将它们应用于标准内容时,过滤器实际上可以正常工作,但这里是多选的.

确实在我的交易模型中:有一个"Deal_goal"属性,我可以选择许多Deal_goal,例如"获取新用户"或"生成热门话题"

以下是我在活动管理表单中输入的方式:

f.input :deal_goal,
        :label      => "Deal goals",
        :as         => :select,
        :multiple   => true,
        :collection => DEAL_GOALS
Run Code Online (Sandbox Code Playgroud)

要进行多重选择,我在Deal模型中对其进行序列化

应用程序/模型/ deal.rb

class Deal < ActiveRecord::Base
  serialize :deal_goal, Array 
Run Code Online (Sandbox Code Playgroud)

我也使用staal.io建议多选('选择'宝石)

我没有做的是在我的索引页面(交易列表)上,对我的Deal_goal属性进行过滤,如果可能的话,在这里有一个多选项,使我能够根据多种目标过滤交易(对于示例:过滤处理目标#1或目标#3)

我尝试了admin/deal.rb下面的两个,但没有一个工作!

filter :deal_goal,    :as => :select, :collection => DEAL_GOALS
filter :deal_goal,    :as => :multiple_select, :collection => DEAL_GOALS
Run Code Online (Sandbox Code Playgroud)

有人有线索吗?

sea*_*ley 7

您可以使用与表单相同的方式创建多项选择,其中包括multiple: true:

filter :deal_goal, as: :select, collection: DEAL_GOALS, multiple: true
Run Code Online (Sandbox Code Playgroud)

UPDATE

从Active Admin/Ransack查询PostgreSQL数组可以完成,只需要多做一些工作.首先,您应该将postgres_ext gem 添加到您的Gemfile中.它为您提供了一组很好的查询方法,您可以像这样使用:

User.where.contains roles: ['foo']
# or:
User.where User.arel_table[:roles].contains ['foo']
Run Code Online (Sandbox Code Playgroud)

下一步是告诉Ransack存在这些查询方法(或"谓词").把它放在初始化器中:

# 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
Run Code Online (Sandbox Code Playgroud)

如果这样,您可以确认Ransack正在接受添加的方法:

User.search(roles_contains: [3,4]).result.to_sql
Run Code Online (Sandbox Code Playgroud)

生成这个SQL:

SELECT "users".* FROM "users"  WHERE ("users"."roles" @> '{"3","4"}')
Run Code Online (Sandbox Code Playgroud)

现在让这些新方法与Active Admin一起使用.

ActiveAdmin.register User do
  filter :roles_array_contains, as: :select, multiple: true, collection: ['foo', 'bar']
end
Run Code Online (Sandbox Code Playgroud)

当然,一定要改变User,并roles以适合您的情况的模式和属性.

最后一点说明.我注意到你serialize :attr, Array在模型中手动设置了.要使您的阵列成为PostgreSQL阵列,您必须array: true在数据库迁移中指定.假设你已经这样做了,那么这个serialize电话是不必要的.事实上,由于某种原因,它似乎打破了这种方法,所以一定要删除它.