タグ付けモデルに 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 エラーが発生しました。)
誰かがより良い答えを持っている場合、または私の方法に関するフィードバックがある場合は、ぜひ聞いてください。