我们的Rails 3应用程序包含模型Person
和Message
。消息可以特定于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是否提供了这样做的方法,还是我必须破解自己类似关联的方法?
答案 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)
}