将多态关联与多对多关联相结合......这个设置是正确的吗?

时间:2011-03-29 06:08:15

标签: ruby-on-rails ruby ruby-on-rails-3 many-to-many polymorphism

我有一个类型模型,我希望这两个视频都有很多类型和配置文件,以便有很多类型。我也希望流派有很多视频和流派有很多个人资料。我理解多态和连接表的东西,所以我想知道我的代码是否会按照我的意图运行。另外,我很感激有关如何访问控制器和视图中的内容的任何建议。

这就是我设想的连接表应该是这样的(我不认为我需要一个精心设计的:has :through关联,因为我在连接表中需要的只是关联而没有别的,所以表赢了没有模特儿:

genres_videos_profiles:
-----------------------------------------------------
id | genre_id | genre_element_id | genre_element_type

这是我的genre.rb:

has_and_belongs_to_many :genre_element, :polymorphic => true

这是video.rb:

has_and_belongs_to_many :genres, :as => :genre_element

这是profile.rb:

has_and_belongs_to_many :genres, :as => :genre_element

这会像我打算一样吗?我想要一些反馈。

3 个答案:

答案 0 :(得分:1)

我认为has_and_belongs_to_many在多态性(如果它甚至有效)方面可能有点难以理解。因此,如果你想做多态的事情,那么你就不能使用任何“通过”语法:

class Genre < ActiveRecord::Base
  has_many :genres_videos_profiles
end

class GenresVideosProfile
  belongs_to :genre
  belongs_to :genre_element, :polymorphic => true

  scope :videos, where(:genre_element_type => "Video")
  scope :profiles, where(:genre_element_type => "Profile")
end

然后你就像使用它一样:

# All genre elements
@genre.genres_videos_profiles.each do |gvp|
  puts gvp.genre_element.inspect
end

# Only video genre elements
@genre.genres_videos_profiles.videos.each do |gvp|
  puts gvp.genre_element.inspect
end

答案 1 :(得分:1)

据我所知,HABTM关联不能是多态的,我在API文档中找不到像你这样的例子。如果您只想连接表,您的代码可能如下所示:

class Genre
  has_and_belongs_to_many :videos
  has_and_belongs_to_many :profiles
end

class Video
  has_and_belongs_to_many :genres
end

class Profile
  has_and_belongs_to_many :genres
end

并像Mike已写的那样访问它:

@genre.profiles
@profile.genres
@genre.videos
@video.genres

迁移(仅限连接表):

class CreateGenresVideosJoinTable < ActiveRecord::Migration
  def self.up
    create_table :genres_videos, {:id => false, :force => true} do |t|
      t.integer :genre_id
      t.integer :video_id
      t.timestamps
    end
  end

  def self.down
    drop_table :genres_videos
  end
end

class CreateGenresProfilesJoinTable < ActiveRecord::Migration
  def self.up
    create_table :genres_profiles, {:id => false, :force => true} do |t|
      t.integer :genre_id
      t.integer :profile_id
      t.timestamps
    end
  end

  def self.down
    drop_table :genres_profiles
  end
end

答案 2 :(得分:1)

查看:http://blog.hasmanythrough.com/2006/4/3/polymorphic-through

对我而言,这是完美而干净的!