rails或基于多个复选框选择的查询

时间:2012-07-02 21:07:13

标签: ruby-on-rails-3 activerecord arel

这似乎应该是一个常见的问题,但我找不到答案。基本上我想要一个包含10个左右复选框的表单,我用check_box_tag创建。提交表单时,我想生成一个查询,返回与任何已检查选项匹配的所有记录。因此,检查的选择数量会有所不同。

所以,例如,如果我有

class Book < ActiveRecord::Base
  belongs_to :author
end

我想生成像

这样的东西

Book.where("author_id = ? or author_id = ?", params[authors[0]], params[authors[1]])如果选中了两个框,等等。

感谢您的任何见解。

2 个答案:

答案 0 :(得分:4)

这对你有用吗?

Book.where(author_id: [array_of_author_ids])

您需要先从params收集author_ids

答案 1 :(得分:0)

我最近不得不做类似的事情,这就是我实现这一目标的方式。它非常聪明(至少我是这么认为的。:))

我创建了一个查询模型,用于序列化JSON中的查询列(文本字段)。我使用表单从用户那里获取带有选择字段的查询数据。

class BookQuery < ActiveRecord::Base
  has_many :books



  # loop through each foreign key of the Book table and create a hash with empty selection
  def self.empty_query
    q = {}
    Book.column_names.each do |column_name|
      next unless column_name.ends_with?("_id")
      q.merge column_name => []
    end
  end
end

我正在使用Author作为例子如下:     &lt;%= form_for @book_query do | f | %GT;       &lt;%for author.author%&gt;         &lt;%= check_box_tag“book_query [query] [author_ids] []”,author.id,false%&gt;         &lt;%= author.name%&gt;       &lt;%end%&gt;       &lt;%= f.submit“保存查询”%&gt;     &lt;%end%&gt;

提交此表单后,您最终得到如下参数: 提交表单后,它会生成以下参数:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"XXXXXXXXXXX", "book_query"=>{"query"=>{"author_ids"=>["2", "3"]}}, "commit"=>"Save Query"}

现在,在BookQuery控制器的创建操作中,您可以执行创建函数始终执行的操作:

def create
  @book_query = BookQuery.build(params[:book_query])
  if @book_query.save
    flash[:success] = "Book query successfully saved."
    redirect_to ...
  else
    flash[:error] = "Failed to save book query."
    render :new
  end
end

但是默认情况下rails会以散列类型序列化数据:

1.9.3p194 :015 > pp BookQuery.find(9).query
BookQuery Load (0.7ms)  SELECT "book_queries".* FROM "book_queries" WHERE "book_queries"."id" = $1 LIMIT 1  [["id", 9]]
"--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nauthor_ids:\n- '2'\n- '3'\n"
=> "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nauthor_ids:\n- '2'\n- '3'\n" 

在BookQuery模型中,添加以下内容:

serialize :query, JSON

但是铁路会将ID更改为字符串:

1.9.3p194 :018 > query = JSON.parse(BookQuery.find(10).query)
BookQuery Load (0.5ms)  SELECT "book_queries".* FROM "book_queries" WHERE "book_queries"."id" = $1 LIMIT 1  [["id", 10]]
=> {"author_ids"=>["2", "3"]} 
1.9.3p194 :019 > query["author_ids"]
=> ["2", "3"]

我所做的是覆盖BookQuery模型中的属性访问器:

以下必须完成,因为哈希返回字符串,而不是整数的ids。

def query=(query)
  query.each_pair do |k, v|
    if query[k].first.present?
      query[k].map!(&:to_i)
    else
      query.except!(k)
    end
  end
  write_attribute(:query, query)
end

# just want to avoid getting nil query's
def query
  read_attribute(:query) || {}
end

要查找具有此查询的图书,您只需将此功能添加到您的图书模型:

def self.find_by_book_query(book_query, options = {})
  options[:conditions] = book_query.query
  find(:all, options)
end

现在,您可以获得基于模型定义Book的可自定义查询字符串,一切都像Rails方式一样。 :)