вопрос об использовании полиморфной ассоциации в рельсах - PullRequest
3 голосов
/ 15 декабря 2010

Как, ребята, я новичок в рельсах, вот мой код:

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

С этого момента я могу использовать drummer.videos, чтобы получить все видео, принадлежащие барабанщику, но я не могуиспользуйте video.drummer, чтобы узнать, кому принадлежит видео.

конечно, я могу использовать video.where (: videoable_id => '1',: videoable_type => 'drummer'), чтобы найтиточная запись барабанщика, но я думаю, что это должно быть элегантно, чтобы делать это в рельсах, верно?

и еще один вопрос, я хочу улучшить эту ассоциацию, видео и барабанщик, видео и тарелка должны быть многогранными-почему, иногда в одном видео более 1 барабанщика или 1 тарелки, поэтому имеет смысл сделать это таким образом.как я могу это сделать?

Ответы [ 3 ]

1 голос
/ 16 декабря 2010
1 голос
/ 17 декабря 2010

Если ваши Drummer и Cymbal модели похожи, вы можете рассмотреть возможность использования STI вместо полиморфизма. Определите новую модель со столбцом at type, который будет выступать в качестве родителя, и добавьте ассоциацию has_many, затем добавьте дочерние модели:

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

Добавление модели SubjectVideo с внешними ключами subject_id и video_id. Затем сделайте так, чтобы ваша видео модель ассоциировалась через него:

class Video < ActiveRecord::Base
  has_many :subject_videos, :dependent => :destroy
  has_many :subjects, :through => :subject_videos
end

Теперь у вас есть связь «многие ко многим».

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]

Основным недостатком этого подхода является то, что Drummer и Cymbal теперь хранятся в одной таблице, что может быть нежелательно, если они имеют несколько столбцов.

Если вам все еще нужны отношения «многие ко многим» с использованием полиморфизма, посмотрите также has_many_polymorphs .

1 голос
/ 15 декабря 2010

Если вы всегда хотите установить отношение один ко многим (у видео может быть максимум один барабанщик), вы можете добавить эти строки в модель видео:

belongs_to :drummer, :class_name => "Drummer", :foreign_key => "videoable_id"
belongs_to :cymbal, :class_name => "Cymbal", :foreign_key => "videoable_id"

Rails определит, к какому классу относится внешний ключ, и выберет правильную запись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...