ruby 我怎样才能得到从多态类到相关类的关联

jv2fixgn  于 12个月前  发布在  Ruby
关注(0)|答案(2)|浏览(146)

我试图让一些多态关联正常工作,但我无法让他们正确。目前,他们给予我任何ID匹配的两个表,而不是直接关系。

class User < ApplicationRecord
  belongs_to :origin, polymorphic: true
  has_one :customer, foreign_key: :id, primary_key: :origin_id, class_name: "Customer"
  has_one :employee, foreign_key: :id, primary_key: :origin_id, class_name: "Employee"
end

class Customer < ApplicationRecord
  has_one :user, class_name: "User", foreign_key: :origin_id
end

class Employee < ApplicationRecord
  has_one :user, class_name: "User", foreign_key: :origin_id
end

如果我这样做:

user = User.create(origin: Customer.find(1))
user.customer # => #<Customer:0x000000014a78d2c8>
# I expect that the code below to be nil but it is not
user.employee # => #<Employee:0x000000014a78d2c8>

有谁知道我怎样才能得到正确的关联?先谢了。

ffdz8vbo

ffdz8vbo1#

在Rails指南中,有一个has_many多态关联的示例
has_one有几乎相同的代码,也阅读更多关于belongs_to关联选项

class User < ApplicationRecord
  belongs_to :origin, polymorphic: true

  belongs_to :customer, -> { where(users: { origin_type: 'Customer' }).includes(:user) }, foreign_key: :origin_id
  belongs_to :employee, -> { where(users: { origin_type: 'Employee' }).includes(:user) }, foreign_key: :origin_id

  # Or simply define instance methods if you don't need above associations:
  # def customer
  #   origin if origin_type == 'Customer'
  # end

  # def employee
  #   origin if origin_type == 'Employee'
  # end
end

class Customer < ApplicationRecord
  has_one :user, as: :origin
end

class Employee < ApplicationRecord
  has_one :user, as: :origin
end

在任何情况下,您都需要这样的模式迁移:

create_table :users do |t| # or change_table if it is existing table
  t.belongs_to :origin, polymorphic: true # origin_id and origin_type columns
end

输出应该是这样的

user = User.create(origin: Customer.find(1))
user.customer # => #<Customer:0x000000014a78d2c8>
user.employee # => nil
v64noz0r

v64noz0r2#

首先,有几件事需要改变,你不需要为customer和employee定义单独的关联,因为你将使用多态关联,并且不需要显式指定主键和外键。
我们应该修改代码如下:

class User < ApplicationRecord
  belongs_to :origin, polymorphic: true
end

class Customer < ApplicationRecord
  has_one :user, as: :origin
end

class Employee < ApplicationRecord
  has_one :user, as: :origin
end

为了了解这是如何工作的,我建议你通过官方文档的活动记录协会https://guides.rubyonrails.org/association_basics.html#polymorphic-associations
对于从客户或员工获取用户记录,您可以分别使用customer.originemployee.origin。如果你想获取用户的相关来源类型,你可以使用user.origin.origin_type

相关问题