我正在嘗試設定一個多型物體 has_one 位置,但一個位置可以屬于許多多型物體。我遇到的困惑是我需要指定多型關聯,而guess check 不起作用,哈哈。
澄清一下,任何“可定位”都應該有一個位置,但一個位置應該能夠有許多與之關聯的可定位。
當前設定:
class User
has_one :locatable_location, as: :locatable
has_one :location, through: :locatable_locations
end
class Entity
has_one :locatable_location, as: :locatable
has_one :location, through: :locatable_locations
end
class LocatableLocation
belongs_to :locatable, polymorphic: true
belongs_to :location
end
class Location
has_many :locatable_locations
has_many :locatables, polymorphic: true, through: :locatable_locations
end
非常感謝任何幫助:)
uj5u.com熱心網友回復:
因為我最終弄清楚了,所以要回答我自己的問題。
錯誤出在位置模型中。改成
class Location
has_many :locatable_locations
has_many :users, through: :locatable_locations, source: :locatable, source_type: :User
has_many :entities, through: :locatable_locations, source: :locatable, source_type: :Entity
end
如果您想與“可定位的”建立關系,即獲取關聯的所有記錄,則必須在 location 中定義一個方法,例如
def locatables
users entities
end
如果您的用例有很多像我這樣的可定位物件,那么您也可以執行類似的操作
class Location
RELATIONS = %i[User Entity]
has_many :locatable_locations
RELATIONS.each do |associated_klass|
has_many associated_klass.to_s.snake_case.to_sym, through: :locatable_locations, source: :locatable, source_type: associated_klass
end
def locatables
RELATIONS.reduce([]) { |all, curr| all.append(send(curr.to_s.snake_case)) }
end
uj5u.com熱心網友回復:
我會考慮你是否只是不必要地過度復雜化。使用多型連接表的唯一實際優勢是您可以在不向表中添加列的情況下使附加模型“可定位”。您實際上不能將它用作同構集合而不冒 N 1 查詢的風險,因為多型關聯不支持預先加載。
這種實作方式也不能保證用戶只能擁有一個“當前位置”——由于簡單的競爭條件,可能會發生重復。一個has_oneASSOCATION實際上只是把一個LIMIT 1上查詢。belongs_to另一方面,只能有一個值。
最簡單的解決方案是簡單地向用戶表和單獨的關聯添加一個外鍵列:
module Locatable
extend ActiveSupport::Concern
included do
belongs_to :location
end
end
class User < ApplicationRecord
include Locatable
end
class Entity < ApplicationRecord
include Locatable
end
class Location < ApplicationRecord
has_many :users
has_many :entities
end
魔法總是有代價的——在這種情況下,它完全削弱了你的資料庫設計。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/380868.html
上一篇:C# 設計模式(2)——原型模式
下一篇:ActionController::UnknownFormat(ActionController::UnknownFormat):銷毀時
