2

タグ付けモデルに 2 つの異なるモデルのポリモーフィックな関連付けを使用しています。すごい、簡単。ただし、これら 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 に答える