我有一个简单的项目标记系统,具有以下结构:
class Item < ActiveRecord::Base
has_many :taggings, :dependent => :destroy
has_many :tags, :through => :taggings
end
class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :item
end
class Tag < ActiveRecord::Base
has_many :taggings, :dependent => :destroy
end
我想在scope
类中添加Item
,以便能够获取具有给定标记集的所有项目(包括集合中的所有标记)
所以我尝试了以下范围:
scope :tag_context, lambda { |context| (context.empty? ? all :
joins(:taggings).where(:taggings => {tag_id => context.collect(&:id)})
)
}
其中context
是Array
个Tag
个对象。
关键是这个范围产生以下sql:
SELECT items.* FROM items INNER JOIN taggings ON taggings.item_id = items.id
WHERE taggings.tag_id IN (1,2)
假设context
包含标记1和2。
我想获得标记1和标记2标记的项目。 所以我假设,像:
SELECT items.* FROM items INNER JOIN taggings as t1 ON t1.item_id = items.id
INNER JOIN taggings as t2 ON t2.item_id = items.id
WHERE t1.tag_id = 1 AND t2.tag_id = 2
我应该如何在Rails范围内进行翻译?
我需要一个范围,以便能够链接Item
类的各种范围。
感谢您的帮助!
答案 0 :(得分:1)
您可以尝试动态构建范围(并且您不需要使用.empty?
进行inject
检查):
scope :tag_context, lambda { |context|
context.collect(&:id).inject(self) do |m, id|
m.joins("INNER JOIN taggings as t#{id} ON t#{id}.item_id = items.id").
where("t#{id}.tag_id = ?", id)
end
}