我正在做一个简单的博客应用程序 - 有帖子,通过posts_tags表有许多标签(我的模型如下)。我实现的是,如果用户点击标签,它将只显示带有该标签的帖子。我想要的是让用户能够选择另一个标签,它只会过滤到同时具有这两个标签的帖子,然后是第三个,然后是第四个等等。我在制作活动记录时遇到困难查询 - 特别是动态的。我得到的最接近的是下面列出的 - 但它在纯SQL中,我想至少在ActiveRecord Rubyland语法中使用它,即使它包含的复杂性。
此外,“有计数2”不起作用,它说“计数”不存在,即使我为其指定名称。但是,它输出在我的表中(计数背后的想法是,如果它包含的数字与我们搜索的标签数量一样多,那么理论上/理想情况下它包含所有标签)
我当前的测试SQL查询
select posts_tags.post_id,count(*) from posts_tags where tag_id=1 or tag_id=3 group by post_id ### having count=2
测试SQL的输出(我知道它不包含很多但只包含一些简单的种子数据)。
post_id | count
---------+-------
1 | 2
2 | 1
我的模特: /post.rb
class Post < ActiveRecord::Base
has_many :posts_tags
has_many :tags, :through => :posts_tags
end
/tag.rb
class Tag < ActiveRecord::Base
has_many :posts_tags
has_many :posts, :through => :posts_tags
end
/poststag.rb
class PostsTag < ActiveRecord::Base
belongs_to :tag
belongs_to :post
end
答案 0 :(得分:1)
尝试:
Post.joins(:tags).where(tags: {id: [1, 3]}).select("posts.id, count(*)").group("posts.id").having("count(*) > 2")
答案 1 :(得分:0)
我认为“count = 2”不正确。它应该是“count(*)= 2”。您的查询将是
select post_id,count(post_id)
from posts_tags
where tag_id = 1 or tag_id = 3
group by post_id
having count(post_id) = 2
答案 2 :(得分:0)
通常,您希望在使用rails时远离编写原始sql。 Active Record有很好的帮助方法,可以让你的sql更具可读性和可维护性。
如果您只有几个标签,则可以为每个标签创建范围(http://guides.rubyonrails.org/active_record_querying.html#scopes)
由于人们一次点击一个标签,您可以只查询每个标签,然后在阵列上使用&
运算符。因为您已经从数据库中请求了完全相同的数据集,所以应该缓存查询结果,这意味着您只是在数据库中访问最新的查询。