【问题标题】:Filtering with AND and OR in Rails query在 Rails 查询中使用 AND 和 OR 进行过滤
【发布时间】:2012-03-02 07:20:08
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-04
      • 2022-10-04
      • 1970-01-01
      • 2021-12-23
      • 2017-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多