2

我正在使用两个不同模型的多态关联到一个标记模型。很好,很简单。但是,这两个模型中的一个也属于另一个模型。

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 错误,我试图链接到另一个引用设施表的范围。)

如果有人有更好的答案,或者对我的方法有一些反馈,我很想听听

4

2 回答 2

0

我看到您已经回答了您的问题,但是如果您要使用:include =>而不是:join =>在原始查询中使用,它将生成一个LEFT OUTER JOIN. 也就是说,您可能不需要预先加载关联,只需对其进行查询,因此您的里程可能会有所不同。

于 2012-12-05T22:09:05.420 回答
0

我想知道你能不能写成这样?

named_scope :by_tag_id, lambda {|tag_id| 
  { 
    :select     => "DISTINCT units.*",
    :include    => [:tags, {:facility => :taggings}],
    :conditions => { :tags => { :tag_id => tag_id } }
  }
}
于 2012-12-06T06:42:47.200 回答