Используя Ruby on Rails, как я могу достигнуть полиморфного has_many
отношения, где владелец всегда имеет известное, но объекты в ассоциации будут иметь некоторых полиморфных (но однородны) тип, указанный столбцом во владельце? Например, предположите Producer
класс has_many
продукты, но экземпляры производителя могли бы на самом деле иметь много Велосипедов, или фруктового мороженого или Шнурков. У меня может легко быть каждый класс продукта (Велосипед, фруктовое мороженое, и т.д.) имеют a belongs_to
отношения к Производителю, но, учитывая экземпляр производителя, как я могу получить набор продуктов, если они имеют переменные типы (на экземпляр производителя)?
Полиморфные ассоциации направляющих позволяют производителям принадлежать многим продуктам, но мне нужны отношения, чтобы быть наоборот. Например:
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
Таким образом, моя таблица Producer уже имеет столбец "типа", который соответствует некоторому классу продукта (например, Велосипед, фруктовое мороженое, и т.д.), но как может я заставлять направляющие позволять мне сделать что-то как:
>> bike_producer.products
#=> [Bicycle@123, Bicycle@456, ...]
>> popsicle_producer.products
#=> [Popsicle@321, Popsicle@654, ...]
Извините, если это очевидно или общее повторение; я испытываю удивительные затруднения при достижении его легко.
Вот обходной путь, который я сейчас использую. Он не предоставляет никаких удобных методов (операций с коллекциями), которые вы получаете от настоящих 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
Другим недостатком является то, что я должен поддерживать отображение строк типов на классы типов, но это можно автоматизировать. Однако для моих целей этого решения будет достаточно.
пожалуйста, возьмите его на формат
class Bicycle < ActiveRecord::Base
belongs_to :bicycle_obj,:polymorphic => true
end
class Popsicle < ActiveRecord::Base
belongs_to :popsicle_obj , :polymorphic => true
end
class Producer < ActiveRecord::Base
has_many :bicycles , :as=>:bicycle_obj
has_many :popsicle , :as=>:popsicle_obj
end
Используйте этот код. Если у вас возникли проблемы с ним, пожалуйста, оставьте комментарий.
class Note < ActiveRecord::Base
belongs_to :note_obj, :polymorphic => true
belongs_to :user
end
class Contact < ActiveRecord::Base
belongs_to :contact_obj, :polymorphic => true
belongs_to :phone_type
end
class CarrierHq < ActiveRecord::Base
has_many :contacts, :as => :contact_obj
has_many :notes, :as => :note_obj
end