开发者

question about using the polymorphic association in rails

开发者 https://www.devze.com 2023-01-30 23:49 出处:网络
How guys I\'m new to rails, here\'s my code: class Video < ActiveRecord::Base belongs_to :videoable, :polymorphic => true

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消