我的Rails应用程序中存在一个难以过滤的问题。用户想要使用标签过滤项目。这没问题,我只使用命名范围。但标签出现在用户可以选择的框中,如下所示:
Size
[XS]
[S]
Color
[Red]
[Blue]
标签位于“tagsets”中,一个标签集为多个标签。
我的问题:当用户想要缩小搜索范围时,如何将多个过滤查询链接在一起?
当用户从第一个框中选择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
答案 0 :(得分:0)
似乎Rails没有提供构建OR查询的方法。所以你必须自己做。 根据模式,一个Item has_and_belongs_to_many:标签,对吧? 在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。