Rails“has_many”与NULL外键关联

时间:2012-05-03 14:53:08

标签: ruby-on-rails ruby-on-rails-3 associations

我们的Rails 3应用程序包含模型PersonMessage。消息可以特定于Person(设置消息person_id列时),也可以是“全局”(当person_id列为NULL时)。

我们希望使用:conditions option建立一个简单的has_many关系:

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强制执行相等的外键约束(例如“FROM messages WHERE person_id=123 AND (person_id IS NULL OR person_id=123)”之后,将“conditions”选项编码为逻辑“AND”子句。 )。似乎没有办法允许具有空外键的关联对象属于这种关联。

Rails 3 / ActiveRecord是否提供了这样做的方法,还是我必须破解自己类似关联的方法?

2 个答案:

答案 0 :(得分:1)

您不能在ActiveRecord关联中使用条件。您可以在没有条件的情况下拥有关联,然后添加一个方法以包含所需的全局消息。这样,在构建相关记录时,您仍然可以利用关联。

# person.rb
has_many :messages

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

这是我Squeel gem的标准插件,如果您不想在代码中使用SQL,则可以方便地进行更高级的查询。看看吧。

答案 1 :(得分: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)
   }