多態性クラスから関連クラスへの関連付けを取得するにはどうすればよいですか
概要
いくつかのポリモーフィックな関連付けを適切に機能させようとしていますが、正しく動作させることができません。現在、直接の関係ではなく、両方のテーブルに一致する 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>
適切な関連付けを取得する方法を知っている人はいますか?前もって感謝します。
解決策
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