3

ActiveRecord では、has_many 関係は外部キー列を使用して関連付けをロードします。そう:

class Person < ActiveRecord::Base
  has_many :messages
end

class Messages < ActiveRecord::Base
  belongs_to :person
end

Person.limit(10).includes(:messages) 
# select * from persons limit 10;
# select messages.* from messages where person_id in (1, 2, 3...)

Rails が自動的に外部キー チェックを where 句に追加することを望まないケースがあります (他の人もこれを求めているのを見てきました)。代わりに、次のようなものが必要になる場合があります。

class Person < ActiveRecord::Base
  has_many :messages, 
           :foreign_key => false, 
           :conditions => proc { ["person_id is null or person_id = ?", self.id] }
end

Person.limit(10).includes(:messages)
# select messages.* from messages where person_id is null or person_id in (1, 2, 3...)

これどうやってするの?要約すると、ActiveRecord が WHERE 句に外部キーを自動的に追加するのは望ましくありません。関連付けに使用する式を指定できるようにしたいのです。

私はこれをしたくありません:

class Person < ActiveRecord::Base
  def messages
    Message.where("person_id is null or person_id = #{ self.id }")
  end
end

私の知る限り、熱心な読み込みが中断されるためです。

finder_sqlまた、has_manyのオプションを使用したくありませんperson.messages.where(:id => 1)Person.limit(10).includes(:messages => :image)

4

1 に答える 1

1

Rails 3.2.1では、次のようなものが機能します。

class Person < ActiveRecord::Base
  has_many :messages, :finder_sql => lambda{ "SELECT * FROM messages WHERE messages.person_id=#{id} OR messages.person_id IS NULL" }
end

# person = Person.includes(:messages).first
# person.messages.loaded?  #=> true
于 2012-09-07T19:35:20.010 に答える