Reputation: 3062
I am noticing a relation problem that I may have created.
I started off with a Photo model. An admin could upload photos and they would exist on the site.
In a later iteration Albums were added into the codebase so that a collection of photos could be organized on its own page.
Album
has_many :photos, inverse_of: :album
Photo
belongs_to :album, inverse_of: :photo
After playing with the above I noticed that a Photo can ever only belong to one Album. That has been ok.
Now a new issue arises. I'd like to add photos of members of the staff which are also their own model.
I also have some special logic in my Photo model to handle using a specific upload service (filepicker).
Staff
field :name, type: String
How can I make it so Staff can have their own photos? Should I create a new model StaffPhoto for denormalization? I was thinking of having Photo either embedded or belong_to Staff but then I'm not sure if it makes sense to belong to both an Album and a Staff member. The only thing making the most sense to me right now is creating a separate model and abstracting the upload service logic into a module and including it into both. However I could be wrong. The important part is that Photo's overall will exist on their own, or a part of an album, or a part Staff member (more than one photo).
Any suggestions on how to model this?
Upvotes: 2
Views: 259
Reputation: 33742
A polymorphic association is good when you have things which belong to different owner classes; e.g. when you have photos which could be from either a movie or a tv-show, and you have movies and tv-shows already modeled in your database -- then you'd use a polymorphic association to refer to the "owner" object of a photo.
Typically you would not want to model Admins, Staff, and Users with separate models. A cleaner way to do this is to model all of them as Users, and then have roles and permissions modeled separately, so e.g. everybody could potentially be an Admin.
If you chose this sort of modeling of users, then all you need in your photo model is a user_id to model who the owner is -- and you don't care if that's an admin or staff, or a regular user.
If you also want to model how the photos are used, e.g. the admin photos are completely different from the staff photos (e.g. admin photos are backgrounds, staff photos are head-shots), then you might want to also assign a "photo type" attribute to the photos.
I don't think that in your scenario a polymorphic association is the best solution.
Please check out the Railscast on Roles/Authorization, so you can model the Admin/Staff in just one model.
http://railscasts.com/episodes?search=authorization
Regarding Embedded Documents:
there are few considerations for using embedded documents:
In case of photos, you would want to embed references to your photos, not the photos themselves, because of the large size a photo can have.
In case of your application, how many photos are there for a user? Can their number grow to a considerable amount over time? If yes, then you probably don't want to embed them.
Does the photo augment the user record? e.g. is it an avatar photo? if not, then you probably don't want to embed it.
Do you ever need to search across the photos? Probably not. Other kinds of embedded document might need to be searched from the top level, and then you can not embed them.
Upvotes: 1
Reputation: 6088
What you are looking for is perfectly described in the guides: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
You could create a polymorphic association:
class Photo < ActiveRecord::Base
belongs_to :photoable, :polymorphic => true
end
class Album < ActiveRecord::Base
has_many :photos, :as => :photoable
end
class Staff < ActiveRecord::Base
has_many :photos, :as => :photoable
end
Upvotes: 1