0

我有两个模型 has_and_belong_to_many 彼此:

class Post < ActiveRecord::Base
  has_and_belongs_to_many :tags, :join_table => :tags_posts
end

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :posts, :join_table => :tags_posts
end

然后我有一个查询:

@tags = Tag.where(name: ["tag1","tag2","tag3"])

我想获得所有具有这些标签的独特帖子,所以我编写了这个丑陋的代码:

@posts = [] 
@tags.each do |tag|
  @posts += tag.posts
end
@posts.uniq!

我想这是低效的,因为@posts 是一个数组而不是“ActiveRecord::Relation”,所以我不能直接使用它上面的所有类方法。有没有更好的方法来实现这一目标?

4

2 回答 2

2
@tags = Tag.where(name: %w(tag1 tag2 tag3)).includes(:posts)

应该做的伎俩(%w()创建一个字符串数组,所以没有区别)。它在一个或两个查询中加载所有带有标签的帖子,无论在 AR 视图中更有效的是什么。然后你可以做

@posts = @tags.map(&:posts).flatten.uniq

获取帖子。map在每个标签上调用posts方法并返回一个包含这些帖子的数组,但是由于您有一个数组数组,所以您想要flatten它。

于 2013-09-10T06:06:19.863 回答
1

includes您可以使用和查询模型来连接这两个表,Post而不是Tag让您获得唯一的帖子。

Post.includes(:tags).where(:tags => { name: %w(tag1 tag2 tag3) })
于 2013-09-10T06:18:19.470 回答