4

Rails3アプリケーションにはモデルPersonとがありMessageます。メッセージは、個人に固有にすることも(メッセージperson_id列が設定されている場合)、「グローバル」にすることもできます(person_id列がNULLの場合)。

このようなオプションを使用して、単純なhas_many関係を作成したいと思います。:conditions

class Person < ActiveRecord::Base
  has_many :messages,
      :conditions => proc { ['(messages.person_id IS NULL) OR ' +
                             '(messages.person_id = ?)'], self.id }
  # ...
end

ただし、has_manyクラスメソッドは、PersonオブジェクトのID( ""など)と等しい外部キー制約を適用した後、"conditions"オプションを論理"AND"句としてエンコードしているようFROM messages WHERE person_id=123 AND (person_id IS NULL OR person_id=123)です。null外部キーを持つ関連付けられたオブジェクトがそのような関連付けに属することを許可する方法はないようです。

Rails 3 / ActiveRecordはこれを行う方法を提供しますか、それとも私自身のアソシエーションのようなメソッドをハックする必要がありますか?

4

2 に答える 2

1

ActiveRecordアソシエーションの条件を使用して、必要なOR句を設定することはできません。条件なしで関連付けを行い、必要なグローバルメッセージを含めるメソッドを追加できます。そうすれば、関連付けられたレコードを作成するときに、関連付けを利用できます。

# person.rb
has_many :messages

def all_messages
  Message.where('messages.person_id=? OR messages.person_id IS NULL', id)
end

これがSqueelgemの標準プラグです。これは、コードにSQLを少し含めたくない場合に、このようなより高度なクエリに便利です。見てみな。

于 2012-05-03T16:28:47.080 に答える
0

あなたは正しいと思います。has_manyを放棄して、次のような外部結合を使用してスコープを作成できます。

class Person < ActiveRecord::Base
   scope :messages lambda { 
      joins("RIGHT OUTER Join messages on persons.id = messages.person_id")
      .where('persons.id = ?',self.id)
   }
于 2012-05-03T15:07:16.927 に答える