Ruby on rails通过复选框在序列化数组中搜索

时间:2016-06-30 07:54:02

标签: ruby-on-rails ruby activerecord serialization

您好我有一个rails应用程序,我以序列化形式存储标签

product.rb

class Product < ActiveRecord::Base

serialize :product_keywords, Array

scope :with_tag, lambda { |tag|

                  where(["product_keywords LIKE ?", "%"+tag.join("%")+"%"])

                 }

end

在视图中我有

<% Product.all.active.each do |product| %>

                  <% product.product_keywords.map do |keywords| %>
                          <div class="checkbox">
                            <label>
                              <%= check_box_tag("with_tag[]", keywords, false) %> <%= keywords.capitalize %>
                            </label>
                         </div>                 
                  <% end %>
              <% end %>

在这里,当我从范围with_tag的复选框中找到带有标签的产品时,它只根据最后选中的复选框获取记录

您可以通过查询

获得清晰的愿景
product_keywords LIKE '%tshirt%printed%'

product_keywords存储在表格的数组中。

如果多个重复标签存储在产品中,我怎样才能找到记录

1 个答案:

答案 0 :(得分:1)

使用LIKE您应为每个代码生成product_keywords LIKE "%#{tag}%"

最后你应该加入SQL&#39; OR&#39;或者&#39; AND&#39;视情况而定(任何标记匹配 - 使用OR,所有标记匹配 - 使用AND

假设你想要&#39; AND&#39;您可以轻松地遍历所有标记以设置范围,如下所示:

class Product < ActiveRecord::Base
  serialize :product_keywords, Array
  scope :with_tag, lambda { |tag| where(["product_keywords LIKE ?", "%#{tag}%") }
end

使用

# we have selected tags in tags
products = Product.all
tags.each { |tag| products = products.with_tag(tag) }

这将为每个标签生成where条件。许多条件通过sql&#39; AND&#39;

加入AR

示例sql输出标签设置为[&#39; tshirt&#39;,&#39;打印&#39;]

... WHERE product_keywords LIKE "%tshirt%" AND product_keywords LIKE "%printed%"

如果你想要&#39;或者&#39;标签条件(匹配任何)你应该构建完整的SQL where子句,例如:

scope :with_any_tag, lambda { |tags|
  # build SQL stmt for all tags, i.e.
  # (product_keywords LIKE ?) OR (product_keywords LIKE ?)
  # replace 'OR' with 'AND' if you need all-matching instead of any-matching
  sql_stmt = tags.collect { |tag| "(product_keywords LIKE ?)" }.join(' OR ')

  # prepare sql placeholder values, i.e.
  # %tsrhit%, %printed%
  sql_placeholders = tags.collect {|tag| "%#{tag}%"}

  # pass conditions and placeholders to where as a list
  # first param is a stmt, then all placeholders
  where([sql_stmt] + sql_placeholders) 
}

这是更通用的解决方案,因为您可以根据具体情况将OR更改为AND,反之亦然。

然后以这种方式使用它:

products = Product.with_any_tag(['tshirt', 'printed'])