ActiveRecord has_many具有自定义外键sql表达式

时间:2012-09-07 04:10:32

标签: ruby-on-rails postgresql activerecord associations

在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)

等内容

1 个答案:

答案 0 :(得分: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