views:

79

answers:

1

Please bear with me for a moment as I try to explain exactly what I would like to achieve.

In my Ruby on Rails application I have a model called Page.

It represents a web page.

I would like to enable the user to arbitrarily attach components to the page. Some examples of "components" would be Picture, PictureCollection, Video, VideoCollection, Background, Audio, Form, Comments.

Currently I have a direct relationship between Page and Picture like this:

class Page < ActiveRecord::Base
  has_many :pictures, :as => :imageable, :dependent => :destroy
end

class Picture < ActiveRecord::Base
  belongs_to :imageable, :polymorphic => true
end

This relationship enables the user to associate an arbitrary number of Pictures to the page. Now if I want to provide multiple collections i would need an additional model:

class PictureCollection < ActiveRecord::Base
  belongs_to :collectionable, :polymorphic => true
  has_many :pictures, :as => :imageable, :dependent => :destroy
end

And alter Page to reference the new model:

class Page < ActiveRecord::Base
  has_many :picture_collections, :as => :collectionable, :dependent => :destroy
end

Now it would be possible for the user to add any number of image collections to the page.

However this is still very static in term of the :picture_collections reference in the Page model. If I add another "component", for example :video_collections, I would need to declare another reference in page for that component type.

So my question is this:

Do I need to add a new reference for each component type, or is there some other way? In Actionscript/Java I would declare an interface Component and make all components implement that interface, then I could just have a single attribute :components which contains all of the dynamically associated model objects.

This is Rails, and I'm sure there is a great way to achieve this, but its a tricky one to Google. Perhaps you good people have some wise suggestions. Thanks in advance for taking the time to read and answer this.

A: 

I believe you can use just

class Page < ActiveRecord::Base
  has_many :components, :as => :attachable, :dependent => :destroy
end

class Picture < ActiveRecord::Base
  belongs_to :attachable, :polymorphic => true
end

class PictureCollection < ActiveRecord::Base
  belongs_to :attachable, :polymorphic => true
  has_many :pictures, :as => :imageable, :dependent => :destroy
end

and so on...

j.
Hi J, I tried this, but i keep getting a`uninitialized constant Page::Component`error when i access Page.componentsDo you have any suggestions how to resolve this?thanks
Globalkeith
I was thinking... maybe you have to define every relation... or define a `Component` class and make `Picture` and `PictureCollection` derive from this class.
j.