-1

我正在做一个简单的博客应用程序 - 有帖子,通过 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
4

3 回答 3

1

试一试:

Post.joins(:tags).where(tags: {id: [1, 3]}).select("posts.id, count(*)").group("posts.id").having("count(*) > 2")
于 2013-06-28T03:35:01.513 回答
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
于 2013-06-28T03:17:35.487 回答
0

通常,您希望在使用 rails 时避免编写原始 sql。Active Record 有很好的辅助方法来让你的 sql 更具可读性和可维护性。

如果您只有几个标签,您可以为每个标签创建范围(http://guides.rubyonrails.org/active_record_querying.html#scopes

由于人们一次单击一个标签,您可以只查询每个标签,然后&在数组上使用运算符。因为您已经从数据库中请求了完全相同的数据集,所以查询结果应该被缓存,这意味着您只针对最新查询访问数据库。

于 2013-06-28T03:51:44.937 回答