mysql - 在 Rails 查询中使用 AND 和 OR 进行过滤

标签 mysql sql ruby-on-rails ruby-on-rails-3 tags

我的 Rails 应用程序有一个困难的过滤问题。用户想要使用标签过滤项目。这没问题,我只是使用命名范围。但是标 checkout 现在用户可以选择的框中,如下所示:

Size
  [XS]
  [S]

Color
  [Red]
  [Blue]

标签在“标签集”中,一个标签集到多个标签。

我的问题:当用户想要缩小搜索范围时,我如何将多个过滤器查询链接在一起?

当用户从第一个框中选择 XS 时,它应该单独过滤该标签上的结果集。当用户选择 XS 和 S 时,我们添加到过滤器并获得更多结果。命名范围仍然不是问题。但是,如果用户想从第二个框中过滤 XS 和 S,然后过滤红色怎么办?那是事情变得棘手的时候 - 我不能只为该标签添加另一个 Item.by_tag("tagname"),它需要成为我已有结果的标签过滤器,从而缩小结果范围。

同一个标签集框中的多个复选框 - 更多结果。检查另一个标签集框 - 结果更少。我尝试为每个标签集框执行一个 SELECT,然后在 ruby​​ 中合并结果集以仅显示所有集中的命中,但这会破坏分页,因为我不知道会返回多少结果。感觉这需要是一个查询,它可能是某种连接,但我不擅长 SQL,我无法弄清楚。架构的相关部分如下所示:

create_table "items" do |t|
  t.string   "title"
end

create_table "items_tags", :id => false do |t|
  t.integer "item_id"
  t.integer "tag_id"
end

create_table "tags" do |t|
  t.string   "title"
  t.integer  "tagset_id"
end

create_table "tagsets" do |t|
  t.string   "title"
end

最佳答案

Rails 似乎没有提供构建 OR 查询的方法。所以你必须自己做。 根据模式,一个 Item has_and_belongs_to_many :tags,对吧? 在 Rails 2.3 中,遵循 named_scopes 应该可以工作。如果您使用的是 Rails 3,则需要重写它。

named_scope :having_tags, lambda { |tagsets| {:joins => :tags, :select => "DISTINCT items.*",
  :conditions => ([Array.new(tagsets.size, "tags.title IN (?)").join(' OR ')] + tagsets) }

然后你这样调用它:

Item.having_tags([['XS', 'S'], ['Red', 'Blue']])

我假设您使用的是 MySQL。

关于mysql - 在 Rails 查询中使用 AND 和 OR 进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9529468/

相关文章:

ruby-on-rails - Ruby/Rails-从我的应用程序中删除ActiveAdmin

ruby-on-rails - RoR 教程 Michael Hartl 5.27

php - mysql中的Concat和Concat_ws

mysql - INSERT ... ON DUPLICATE KEY UPDATE 不起作用

mysql - 缓慢的 MySQL "INNER JOIN"

php - MySQL:在不破坏外键约束的情况下消除重复行

sql - 不带avg功能的平均值

sql - 无法修复此查询中从 varchar 到 int 的类型转换问题,我写道

ruby-on-rails - 如何在 RSpec 测试中剔除 PDF 生成?

php - 我似乎无法弄清楚为什么我的图像上传脚本不起作用