Пожалуйста, потерпите меня на мгновение, поскольку я пытаюсь объяснить, чего именно я хотел бы достичь.
В моем приложении на Ruby on Rails есть модель под названием Page.
Представляет веб-страницу.
Я бы хотел, чтобы пользователь мог произвольно прикреплять компоненты к странице. Некоторыми примерами «компонентов» могут быть Picture, PictureCollection, Video, VideoCollection, Background, Audio, Form, Comments.
В настоящее время у меня есть прямая связь между Page и Picture следующим образом:
class Page < ActiveRecord::Base
has_many :pictures, :as => :imageable, :dependent => :destroy
end
class Picture < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
end
Это отношение позволяет пользователю связать произвольное количество изображений на странице. Теперь, если я хочу предоставить несколько коллекций, мне нужна дополнительная модель:
class PictureCollection < ActiveRecord::Base
belongs_to :collectionable, :polymorphic => true
has_many :pictures, :as => :imageable, :dependent => :destroy
end
И измените страницу для ссылки на новую модель:
class Page < ActiveRecord::Base
has_many :picture_collections, :as => :collectionable, :dependent => :destroy
end
Теперь пользователь сможет добавлять на страницу любое количество коллекций изображений.
Однако это все еще очень статично с точки зрения ссылки: picture_collections в модели страницы. Если я добавлю еще один «компонент», например: video_collections, мне нужно будет объявить еще одну ссылку на странице для этого типа компонента.
Так что мой вопрос таков:
Нужно ли добавлять новую ссылку для каждого типа компонента или есть какой-то другой способ? В Actionscript / Java я объявил бы компонент интерфейса и заставил бы все компоненты реализовать этот интерфейс, тогда я мог бы просто иметь один атрибут: компоненты, которые содержат все динамически связанные объекты модели.
Это Rails, и я уверен, что есть отличный способ добиться этого, но он сложен для Google. Возможно, у вас, хороших людей, есть несколько мудрых предложений. Заранее спасибо, что нашли время, чтобы прочитать и ответить на этот вопрос.