Rails:为Mongoid数据库创建基于下拉列表的搜索过滤器

时间:2018-08-31 19:20:52

标签: ruby-on-rails mongodb mongoid

在我的索引页面上,我有一些下拉列表,用户可以选择这些下拉列表作为搜索Mongo集合的过滤器。这些下拉菜单对应于我的模型中设置的字段。还有一个开放的文本输入字段,它们可用于搜索集合中的文本字段“方案名称”和“方案主体”。我似乎找不到太多有关如何链接Mongoid查询以缩小搜索范围的文档。

index.erb视图页面上有一个form_tag,其中包含我要用户搜索的字段的各种选择器,以及用于方案名称和正文字段的文本输入。

这是我的索引控制器:

  def index
@scenarios = if params[:search]
               Scenario.search(params)
             else
               Scenario.all
             end
end

还有我的“场景”模型:

class Scenario
  include Mongoid::Document
  field :submitter, type: String
  field :scenario_name, type: String
  field :scenario_body, type: String
  field :creation_date, type: Date
  field :modified_date, type: Date
  field :test_type, type: String
  field :application, type: String
  field :pillar, type: String

  def self.search(search)
    self.or({submitter: /.*#{search[:submitter]}.*/i},
            {scenario_name: /.*#{search[:search]}.*/i},
            {scenario_body: /.*#{search[:search]}.*/i},
            {creation_date: search[:creation_date]},
            {modified_date: search[:modified_date]},
            {test_type: /.*#{search[:test_type]}.*/i},
            {application: /.*#{search[:application]}.*/i},
            {pillar: /.*#{search[:pillar]}.*/i})
  end
end

我应该如何创建可以对一个或多个所有下拉选项和一个开放文本搜索进行过滤的方法或查询?

1 个答案:

答案 0 :(得分:0)

这就是我要做的。看起来一点也不像铁轨,但它可以工作。

在场景模型中:

  def self.search(search)
    search_array = [{scenario_name: (/.*#{search[:search]}.*/i if search[:search].present?)},
                    {scenario_body: (/.*#{search[:search]}.*/i if search[:search].present?)}]

    search_array.map {|a| a.reject! {|k, v| v.nil?}}
    search_array.delete_if {|hash| hash.empty?}

    select_array = [{submitter: (search[:submitter] if search[:submitter].present?)},
                    {test_type: (search[:test_type] if search[:test_type].present?)},
                    {application: (search[:application] if search[:application].present?)},
                    {pillar: (search[:pillar] if search[:pillar].present?)}]

    select_array.map {|a| a.reject! {|k, v| v.nil?}}
    select_array.delete_if {|hash| hash.empty?}

    mongo_query = ['$and' => (select_array if select_array.present?), '$or' => (search_array if search_array.present?)]
    mongo_query.map {|a| a.reject! {|k, v| v.nil?}}
    mongo_query.delete_if {|hash| hash.empty?}

    where(mongo_query[0]).to_a
  end