我正在使用两种不同模型的多态关联到标记模型。很棒,很容易。但是,这两个模型中的一个也属于另一个模型。
class Facility < ActiveRecord::Base
has_many :units
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings
end
class Unit < ActiveRecord::Base
belongs_to :facility
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings
end
class Tagging < ActiveRecord::Base
belongs_to :taggable, :polymorphic => true
belongs_to :tag
end
class Tag < ActiveRecord::Base
has_many :taggings
end
我正在尝试编写一个范围来检索某个标记的所有单位,包括那些属于具有该标记的工具的单位。这不起作用:
named_scope :by_tag_id, lambda {|tag_id|
{
:select => "DISTINCT units.*",
:joins => [:taggings, {:facility => :taggings}],
:conditions => ["taggings.tag_id = ? OR taggings_facilities.tag_id = ?",
tag_id.to_i, tag_id.to_i]
}}
对于那个named_scope,我只获得那些带有标记的单位。
有什么想法?我错过了一些明显的东西吗?
更新
不幸的是,我在Rails 2.3.x,Ruby 1.8.7上。
我正在尝试使用更明确编写的连接的一些技术。
更新2
我无法回答我自己的问题,因为我没有声誉。哎呀。我真的应该贡献更多......
嗯,我想我只需要戳一下,再推一点。这就是我的工作:
named_scope :by_tag_id, lambda {|tag_id|
{
:select => "DISTINCT units.*",
:joins => [
"INNER JOIN facilities as bti_facilities ON units.facility_id = bti_facilities.id",
"LEFT JOIN taggings AS bti_facilities_taggings
ON bti_facilities_taggings.taggable_id = bti_facilities.id AND bti_facilities_taggings.taggable_type = 'Facility'",
"LEFT JOIN taggings AS bti_units_taggings ON bti_units_taggings.taggable_id = units.id AND bti_units_taggings.taggable_type = 'Unit'",
],
:conditions => ["bti_units_taggings.tag_id = ? OR bti_facilities_taggings.tag_id = ?", tag_id.to_i, tag_id.to_i]
}
}
我正在使用一些有意混淆的表别名,以便尽量避免与其他命名范围发生冲突。 (我没有设备别名启动,我在查询中遇到SQL错误,我试图链接另一个引用设施表的范围。)
如果有人有更好的答案或对我的方法有一些反馈,我会爱来听取它。
答案 0 :(得分:0)
我发现您已经回答了问题,但如果您在原始查询中使用:include =>
而不是:join =>
,则会生成LEFT OUTER JOIN
。也就是说,您可能不需要急切加载关联,只需查询它,因此您的里程可能会有所不同。
答案 1 :(得分:0)
我想知道你能不能写出这样的东西?
named_scope :by_tag_id, lambda {|tag_id|
{
:select => "DISTINCT units.*",
:include => [:tags, {:facility => :taggings}],
:conditions => { :tags => { :tag_id => tag_id } }
}
}