0

假设您有一个 posts 表和一个 tags 表,两者都由 post_tags 表关联。

所以

帖子有 id/subject/body 列

标签有 id/name

post_tags 有 id/post_id/tag_id

在 Rails 术语中,我有一个 Post 模型,它通过 AssetTags 有许多标签。

我正在尝试查询具有 2 个特定标签的帖子。所以如果有一个rails标签和一个mysql标签,我想要一个返回只有这两个标签的帖子的查询。

说得通?

有什么方法可以使用 activerecord(我正在使用搜索逻辑)或 mysql 来做到这一点?

4

4 回答 4

2

此 SQL 返回包含两个标签的帖子。

select 
  p.* 
from 
  posts p
  ,asset_tags atg1
  ,asset_tags atg2
  ,tags t1
  ,tags t2
where
  p.id = atg1.post_id
and t1.id = atg1.tag_id
and t1.tag = 'MySQL' 
and p.id = atg2.post_id
and t2.id = atg2.tag_id
and t2.tag = 'Rails'
;

至于通过 Active Record 进行操作,另一种方法是查询每个标签,然后查询结果数组以获得两者的交集。

于 2011-11-03T11:32:58.403 回答
0

对于mysql,当然可以获取数据

 SELECT p.*
   FROM posts p 
   JOIN post_tags pt
     ON p.post_id = pt.post_id
  WHERE pt.tag_id in (tagId1, tagId2)

我没有使用过 Rails ActiveRecord 但我想它会是类似的东西

 get('posts');
 join('post_tags','post_id');
 where_in('tag_id', array(tagId1, tagId2);
 execute();
于 2011-11-03T07:14:41.393 回答
0

鉴于这些模型:

def Post
  has_many :asset_tags
  has_many :tags, :through => :asset_tags
end

def AssetTag
  has_one :post
  has_one :tag
end

def Tag
  has_many :asset_tags
  has_many :posts, :through => :asset_tags
end

你可以这样做:

Post.joins(:asset_tags => :tag).where(
  "tags.name in ('?', '?')", 'foo', 'bar' )

现在,这实际上对关联没有任何作用has_many :through——我不确定是否提供了一个更光滑的 api 来利用它。

于 2011-11-03T07:25:33.063 回答
0

John Bachir 的答案可以修改为...

Post.joins(:asset_tags => :tag)
    .where("tags.name in ('?')", 'foo')
    .where("tags.name in ('?')", 'bar')
于 2011-11-03T11:39:02.627 回答