How guys I'm new to rails, here's my code:
class Video < ActiveRecord::Base
belongs_to :videoable, :polymorphic => true
end
class Drummer < ActiveRecord::Base
has_many :videos,:as => :videoable
end
class Cymbal < ActiveRecord::Base
has_many :videos, :as => :videoable
end
From this point I can use the drummer.videos
to get all the video that belong to drummer,
But I can't use video.drummer to get who is the video belongs to.
of course I can use video.where(:videoable_id => '1', :videoable_type => 'drummer') to get the to find the exact drummer record, but I think there must be a elegant to do that in rails, right?
and one more question, I want to improve this association, video and drummer, video and cymbal should be many-to-many, sometime there are more than 1 drummer or 1 cymbal in one video, so it makes sense do it this way开发者_开发知识库. how can I do this?
If it's always a one-to-many relationship that you want (a video can at most have one drummer), you can add these lines to your Video model:
belongs_to :drummer, :class_name => "Drummer", :foreign_key => "videoable_id"
belongs_to :cymbal, :class_name => "Cymbal", :foreign_key => "videoable_id"
Rails will figure out what class the foreign key maps to and fetch the correct entry.
You might be looking for video.videoable
and many-to-many join tables.
- http://apidock.com/rails/ActiveRecord/Associations/ClassMethods
- http://railscasts.com/episodes/47-two-many-to-many
- http://railscasts.com/episodes/154-polymorphic-association
If your Drummer
and Cymbal
models are similar, you might consider using STI instead of polymorphism. Define a new model with at type
column to act as a parent, and add the has_many
association, then add the child models:
class Subject < ActiveRecord::Base
has_many :subject_videos, :dependent => :destroy
has_many :videos, :through => :subject_videos
end
class Drummer < Subject
end
class Cymbal < Subject
end
Add a SubjectVideo model with foreign keys subject_id
and video_id
. Then make your Video model associate through it:
class Video < ActiveRecord::Base
has_many :subject_videos, :dependent => :destroy
has_many :subjects, :through => :subject_videos
end
Now you have a many-to-many association.
d = Drummer.create
d.videos # []
d.videos.create(:name=>"Stompin' at the Savoy")
v = Video.find_by_name("Stompin' at the Savoy")
v.subjects # [Drummer]
The primary drawback of this approach is that Drummer and Cymbal are now stored in the same table, which can be undesirable if they share few columns.
If still need a many-to-many relationship using polymorphism, also take a look at has_many_polymorphs.
精彩评论