动态has_many class_name使用多态引用

时间:2015-04-02 12:01:48

标签: ruby-on-rails activerecord polymorphism

我正在尝试根据Product多态参考将多态模型(在本例中为StoreOnePurchase)与动态类名称(StoreTwoPurchasestore_type)相关联products表上的列。

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

StoreOnePurchaseStoreTwoPurchase必须是单独的模型,因为它们包含非常不同的表格结构,StoreOneStoreTwo也是如此。

我知道引入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

但是我有兴趣看看是否有可能没有额外的桌子?

1 个答案:

答案 0 :(得分:1)

非常有趣的问题。但是,遗憾的是,如果没有额外的表,就不可能,因为没有多态has_many关联。 Rails不能像Product.purchases(belongs_to)那样动态地确定Product.store(has_many)的类型。因为purchases_type中没有Product列,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以支持您的类中的多态类型,但它正在重新发明Rails。

我宁愿改变数据库架构。