mae*_*ics 13 ruby-on-rails associations polymorphic-associations
使用Ruby on Rails,我如何实现多态has_many关系,其中所有者始终是已知的,但关联中的项目将具有某种多态(但同质)类型,由所有者中的列指定?例如,假设Producer类has_many产品但生产者实例可能实际上有许多自行车,或者冰棒或鞋带.我可以很容易地让每个产品类(自行车,冰棒等)belongs_to与生产者有关系但是给定生产者实例如果它们的类型不同(每个生产者实例),我如何获得产品集合?
Rails多态关联允许生产者属于许多产品,但我需要这种关系是另一种方式.例如:
class Bicycle < ActiveRecord::Base
belongs_to :producer
end
class Popsicle < ActiveRecord::Base
belongs_to :producer
end
class Producer < ActiveRecord::Base
has_many :products, :polymorphic_column => :type # last part is made-up...
end
Run Code Online (Sandbox Code Playgroud)
所以我的Producer表已经有一个"类型"列,它对应于某个产品类(例如Bicycle,Popsicle等),但是我怎样才能让Rails让我做类似的事情:
>> bike_producer.products
#=> [Bicycle@123, Bicycle@456, ...]
>> popsicle_producer.products
#=> [Popsicle@321, Popsicle@654, ...]
Run Code Online (Sandbox Code Playgroud)
对不起,如果这是显而易见的或常见的重复; 我很难轻易实现它.
您必须在生产者身上使用STI,而不是在产品上使用.这样,每种类型的生产者都有不同的行为,但在一个producers表中.
(几乎)没有多态性!
class Product < ActiveRecord::Base
# does not have a 'type' column, so there is no STI here,
# it is like an abstract superclass.
belongs_to :producer
end
class Bicycle < Product
end
class Popsicle < Product
end
class Producer < ActiveRecord::Base
# it has a 'type' column so we have STI here!!
end
class BicycleProducer < Producer
has_many :products, :class_name => "Bicycle", :inverse_of => :producer
end
class PopsicleProducer < Producer
has_many :products, :class_name => "Popsicle", :inverse_of => :producer
end
Run Code Online (Sandbox Code Playgroud)
这是我当前正在使用的解决方法。它不提供任何从真实的 ActiveRecord::Associations 获得的便捷方法(集合操作),但它确实提供了一种获取给定生产者的产品列表的方法:
class Bicycle < ActiveRecord::Base
belongs_to :producer
end
class Popsicle < ActiveRecord::Base
belongs_to :producer
end
class Producer < ActiveRecord::Base
PRODUCT_TYPE_MAPPING = {
'bicycle' => Bicycle,
'popsicle' => Popsicle
}.freeze
def products
klass = PRODUCT_TYPE_MAPPING[self.type]
klass ? klass.find_all_by_producer_id(self.id) : []
end
end
Run Code Online (Sandbox Code Playgroud)
另一个缺点是我必须维护类型字符串到类型类的映射,但这可以自动化。然而,这个解决方案足以满足我的目的。
| 归档时间: |
|
| 查看次数: |
8634 次 |
| 最近记录: |