私たちのRails 3アプリケーションはPerson
とMessage
のモデルを持っています。メッセージは、メッセージにperson_id
列が設定されている場合はPersonに固有のメッセージ、またはperson_id
列がNULLの場合はグローバルになります。Rails "foreign_key"との "has_many"関連
我々が使用して簡単なhas_many
関係を持ちたい:conditions
optionなど:
class Person < ActiveRecord::Base
has_many :messages,
:conditions => proc { ['(messages.person_id IS NULL) OR ' +
'(messages.person_id = ?)'], self.id }
# ...
end
しかし、has_many
クラスメソッドを強制した後に論理「AND」句などのオプションを「条件」をコードしていることが表示されますPersonオブジェクトのidと等しい外部キー制約(例: "FROM messages WHERE person_id=123 AND (person_id IS NULL OR person_id=123)
")。ヌルの外部キーを持つ関連オブジェクトがそのような関連に属することを許可する方法はないようです。
Rails 3/ActiveRecordはこれを行う方法を提供していますか、私自身の関連付けのようなメソッドをハックする必要がありますか?あなたは上の条件を使用したいようにあなたがOR句を持つことができません
class Person < ActiveRecord::Base
scope :messages lambda {
joins("RIGHT OUTER Join messages on persons.id = messages.person_id")
.where('persons.id = ?',self.id)
}
残念ながら、これは、all_messagesが関連ではないため、Person.limit(2).includes(:all_messages)のようなことはできません。 –
@JoeVanDykはい、そうです。しかし、includes(:all_messages)を実行すると、eager-loadingを実行するために余分なSQLクエリが実行されます。シンタックスを超えても、私の提案とパフォーマンスの点では大きな違いはありません。 –
includes(:all_messages)を実行すると、最大で1つの追加クエリが発生します。 Person.limit(100).includes(:all_messages)を実行した場合は、2つのクエリが発生します。上記の#all_messagesを使用した場合は、すべてをロードするために101クエリになります。 –