モデルの関連付けを多用するプロジェクトに取り組んでいますが、has_manyまたはhas_one through機能が:conditions機能と競合するケースを見つけたようです。一言で言えば、問題は、throughアソシエーションがhas_onethrough関係の中間テーブルのテーブルエイリアスを作成することです。しかし、そのテーブルエイリアスを定義した条件で表示する方法がわかりません。それを理解するのが難しい場合は、コードが役立つ可能性があります。
class Event < ActiveRecord::Base
has_one :event_intake, :conditions => ['event_intakes.is_draft = 1']
has_many :product_instances, :through => :event_intake
end
class EventIntake < ActiveRecord::Base
belongs_to :event
has_many :product_instances, :conditions => ['is_deleted = ?', '0']
end
class ProductInstance < ActiveRecord::Base
belongs_to :event_intake
end
これが私が得ているMySQLクエリとエラーです:
Mysql2::Error: Unknown column 'event_intakes.is_draft' in 'on clause':
SELECT DISTINCT `events`.id FROM `events`
LEFT OUTER JOIN `event_intakes` product_instances_events_join ON (`events`.`id` = `product_instances_events_join`.`event_id`)
LEFT OUTER JOIN `product_instances` ON (`product_instances`.`event_intake_id` = `product_instances_events_join`.`id`) AND event_intakes.is_draft = 1
WHERE (product_instances.serial_number = '313') ORDER BY events.id DESC LIMIT 0, 50
スルーアソシエーションは、event_intakesテーブルを「product_instances_events_join」としてエイリアスします。ただし、条件event_intakes.is_draftのテーブルは、それに一致するように変更されません。
レール2.3.11を使用していますが、問題はレール3にも同様に当てはまると思います。スルーアソシエーションはhas_oneではなくhas_manyでのみ使用する必要があることを読みましたが、これが原因ではないと思います。問題。
条件を「product_instances_events_join.is_draft=1」に変更した場合、この特定のケースの問題は修正されますが、テーブルエイリアスがない場合は問題が発生します。has_one条件で文字列補間を使用して、正しいテーブル名を取得できれば便利です。次のようなもの:has_one:event_intake、:conditions => ["#{EventIntake.table_name} .is_draft = 1"]エイリアシングが発生してもEventIntakeのtable_nameは変更されないため、上記のコードは機能しないと思います。
私が試したもう1つのことは、クエリを実行する直前に、エイリアシングが発生する前に、has_manyアソシエーションをオンザフライで再定義することです。Event.has_one:event_intake、:conditions => ['product_instances_events_join.is_draft=1']信じてくださいこれでwebrickの問題は実際に修正されましたが、他のスレッドに影響を与える可能性のあるグローバル変数を変更するのと同じだと思うので、マルチスレッドの乗客環境でこのアプローチを使用することを躊躇しています。その上、それはハックです。
誰かがこれを修正する方法について何か提案がありますか?どんな助けでも大歓迎です。