动态 has_many class_name 使用多态引用
Dynamic has_many class_name using polymorphic reference
我正在尝试将多态模型(在本例中为 Product
)关联到基于 class 的动态名称(StoreOnePurchase
或 StoreTwoPurchase
) =17=] products
table.
上的多态引用列
class Product < ActiveRecord::Base
belongs_to :store, polymorphic: true
has_many :purchases, class_name: (StoreOnePurchase|StoreTwoPurchase)
end
class StoreOne < ActiveRecord::Base
has_many :products, as: :store
has_many :purchases, through: :products
end
class StoreOnePurchase < ActiveRecord::Base
belongs_to :product
end
class StoreTwo < ActiveRecord::Base
has_many :products, as: :store
has_many :purchases, through: :products
end
class StoreTwoPurchase < ActiveRecord::Base
belongs_to :product
end
StoreOnePurchase
和 StoreTwoPurchase
必须是不同的模型,因为它们包含非常不同的 table 结构,StoreOne
和 StoreTwo
.[=23 也是如此=]
我知道引入 HABTM 关系可以像这样解决这个问题:
class ProductPurchase < ActiveRecord::Base
belongs_to :product
belongs_to :purchase, polymorphic: true
end
class Product < ActiveRecord::Base
belongs_to :store, polymorphic: true
has_many :product_purchases
end
class StoreOnePurchase < ActiveRecord::Base
has_one :product_purchase, as: :purchase
delegate :product, to: :product_purchase
end
但是我有兴趣看看是否可以不用额外的 table?
非常有趣的问题。但是,不幸的是,没有额外的 table 是不可能的,因为没有多态的 has_many
关联。 Rails 将无法像 Product.store
(belongs_to) 那样动态地确定 Product.purchases
(has_many) 的类型。因为 Product
中没有 purchases_type
列,并且 has_many
中不支持任何动态解析的关联类型。你可以像下面这样做一些技巧:
class Product < ActiveRecord::Base
class DynamicStoreClass
def to_s
#return 'StoreOnePurchase' or 'StoreTwoPurchase'
end
end
belongs_to :store, polymorphic: true
has_many :purchases, class_name: DynamicStoreClass
end
它不会抛出错误,但它是无用的,因为它只会在实例化产品之前调用 DynamicStoreClass.to_s 一次。
您也可以覆盖 ActiveRecord::Associations::association
以支持 class 中的多态类型,但它正在重新发明 Rails。
我宁愿更改数据库架构。
我正在尝试将多态模型(在本例中为 Product
)关联到基于 class 的动态名称(StoreOnePurchase
或 StoreTwoPurchase
) =17=] products
table.
class Product < ActiveRecord::Base
belongs_to :store, polymorphic: true
has_many :purchases, class_name: (StoreOnePurchase|StoreTwoPurchase)
end
class StoreOne < ActiveRecord::Base
has_many :products, as: :store
has_many :purchases, through: :products
end
class StoreOnePurchase < ActiveRecord::Base
belongs_to :product
end
class StoreTwo < ActiveRecord::Base
has_many :products, as: :store
has_many :purchases, through: :products
end
class StoreTwoPurchase < ActiveRecord::Base
belongs_to :product
end
StoreOnePurchase
和 StoreTwoPurchase
必须是不同的模型,因为它们包含非常不同的 table 结构,StoreOne
和 StoreTwo
.[=23 也是如此=]
我知道引入 HABTM 关系可以像这样解决这个问题:
class ProductPurchase < ActiveRecord::Base
belongs_to :product
belongs_to :purchase, polymorphic: true
end
class Product < ActiveRecord::Base
belongs_to :store, polymorphic: true
has_many :product_purchases
end
class StoreOnePurchase < ActiveRecord::Base
has_one :product_purchase, as: :purchase
delegate :product, to: :product_purchase
end
但是我有兴趣看看是否可以不用额外的 table?
非常有趣的问题。但是,不幸的是,没有额外的 table 是不可能的,因为没有多态的 has_many
关联。 Rails 将无法像 Product.store
(belongs_to) 那样动态地确定 Product.purchases
(has_many) 的类型。因为 Product
中没有 purchases_type
列,并且 has_many
中不支持任何动态解析的关联类型。你可以像下面这样做一些技巧:
class Product < ActiveRecord::Base
class DynamicStoreClass
def to_s
#return 'StoreOnePurchase' or 'StoreTwoPurchase'
end
end
belongs_to :store, polymorphic: true
has_many :purchases, class_name: DynamicStoreClass
end
它不会抛出错误,但它是无用的,因为它只会在实例化产品之前调用 DynamicStoreClass.to_s 一次。
您也可以覆盖 ActiveRecord::Associations::association
以支持 class 中的多态类型,但它正在重新发明 Rails。
我宁愿更改数据库架构。