我有多态关系:
class User < ActiveRecord::Base
has_one :address
end
class Group < ActiveRecord::Base
has_one :address
end
与
class Address < ActiveRecord::Base
belongs_to :owner, polymorphic: true
end
如果存在,我想向has_one :user
模型添加has_one :group
和Address
关系。
使用Rails3,它有效:
class Address < ActiveRecord::Base
belongs_to :user, conditions: ['owner_type = ?', 'User']
belongs_to :group, conditions: ['owner_type = ?', 'Group']
end
但是现在条件在Rails4中消失了,我不知道如何处理这个问题。
我试过了:
class Address < ActiveRecord::Base
belongs_to :user, -> {user_owner}, class_name: 'User', foreign_key: 'owner_id'
scope :user_owner, where(owner_type: 'User')
end
但由于在User
模型中搜索范围并且出现user.owner_type does not exist
错误,因此无效。
最后,我希望能够编写例如:Address.joins(:user).where(whatever: true)
答案 0 :(得分:2)
has_one
不是正确的方法,因为地址belongs_to
owner
和has_one
期望foreign_key位于关联表中。
如果我理解正确,如果所有者为address.user
,则您希望User
返回用户实例,否则返回nil
(与address.group
相反)。如果是这种情况,您可以为此创建一个简单的方法:
class Address < ActiveRecord::Base
belongs_to :owner, polymorphic: true
def user
owner_type == "User" ? self.owner : nil
end
def group
owner_type == "Group" ? self.owner : nil
end
#these may create some confusion, but they will only be used with joins
#maybe wrap them in their own Concern to have all the code in one
#location to make it clear for other team members
#user_for_join will return the wrong association is address.owner_type != "User"
belongs_to :user_for_join, foreign_key: :owner_id, class_name: User
#group_for_join will return the wrong association is address.owner_type != "Group"
belongs_to :group_for_join, foreign_key: :owner_id, class_name: Group
def self.address_with_users
#instead of calling Address.joins(:user), you now call Address.address_with_users
self.where(owner_type: "User").joins(:user_for_join)
end
def self.address_with_groups
self.where(owner_type: "Group").joins(:group_for_join)
end
end
答案 1 :(得分:0)
Rails Test code有一个例子,他们使用lambda
belongs_to :user_with_conditions, -> { where :owner_type => 'User'}, :polymorphic => true,