A User can Upload a Clip via the Clips Scaffold
, this clip either belongs to a Show
and or an Album
(Show Controller, Album Controller).
A user can have
A User can Upload Clips, these clips can be attached to either a Show or/and an Album
For a more detailed overview take a look at the image below:
Problem #1 What i'm not understanding is the associations i must use. My current Models:
User Model:
has_many :clips, dependent: :destroy
has_one :show, dependent: :destroy
has_many :albums, dependent :destroy
Clip Model: belongs_to :user
Show Model: belongs_to :user
Album Model: belongs_to :user
---------------------------------------------------------------------------------
Problem #2 I'm not sure on how to accomplish, that when a user uploads a Clip, he can attach (or assign) it to a Show or Album.
What i did with the Show (because there is only one) was just to call <%= @user.clip %> on the View Page.
That means that every clip a user upload's appears on the Show.
Which is wrong...
Now that i have a Show AND an Album i must grand the user the ability to choose where to attach it (On one of the many albums he have, or his Show).
Or should i go with a solution where the User can Upload a Clip THROUGH the Albums or Show controller (not through the separate Clips Controller)
I really could need some help here :)
Your problem #1 is a textbook case of polymorphic association.
class User < ActiveRecord::Base
has_one :show,
:dependent => :destroy
has_many :clips,
:dependent => :destroy
has_many :albums,
:dependent => :destroy
end
class Clip < ActiveRecord::Base
belongs_to :user
belongs_to :attachable,
:polymorphic => true
end
class Show < ActiveRecord::Base
belongs_to :user
has_many :clips,
:as => :attachable
end
class Album < ActiveRecord::Base
belongs_to :user
has_many :clips,
:as => :attachable
end
You can learn more about polymorphic associations at Rails Guides.
Now for your problem #2, assuming you do your migrations as per the guide linked above you'll have two database fields in your clips
table:
attachable_id
- This is the id
of the instance of Show
or Album
that's going to receive the association.
attachable_type
- This is the class name of the target object, so either Show
or Album
.
In your upload form, you're going to show a list of shows and/or albums and assign the id
to attachable_id
and the class name to attachable_type
.
I would suggest loading up your initial select with only one class and then replacing its contents via JavaScript in case the user selects the second option. Like so:
<%= f.collection_select :attachable_type, [['Show'], ['Album']], :first, :first, { :selected => 'Show' }, { :include_blank => false } %>
<%= f.collection_select :attachable_id, Show.all, :id, :name %>
I think that unless there's some reason they all must belong to the user, you can simplify this a lot by making better use of your clip
model.
Change your relationships to this:
User.rb
has_many :clips, dependent: :destroy
Clip.rb
belongs_to :user
has_one :show
has_many :albums
Show.rb
belongs_to :clip
Album.rb
belongs_to :clip
You can see the show by using clip.show
and the albums by using clip.albums
- individual albums can be called by using clip.albums.find(params[:id])