多个模型的多对多关联

时间:2014-06-15 13:15:44

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

我们在Rails 4中对3个模型的多对多关联存在问题。让我们看看:

类别多对多玩家
播放器多对多视频
视频多对多类别

class Player < ActiveRecord::Base
  has_many :playlists
  has_many :categories, through: :playlists
  has_many :videos, through: :playlists
end

class Video < ActiveRecord::Base
  has_many :playlists
  has_many :categories, through: :playlists
  has_many :players, through: :playlists
end

class Category < ActiveRecord::Base
  has_many :playlists
  has_many :videos, through: :playlists
  has_many :players, through: :playlists
end

class Playlist < ActiveRecord::Base
  belongs_to :video
  belongs_to :player
  belongs_to :category
end

当我们创建包含2个玩家和2个视频的新类别时,相关模型的关系不会相互联系。

@category = current_user.categories.create(category_params)

在表中我们看到:

#<Playlist id: 37, video_id: nil, player_id: 1, category_id: 87>, 
#<Playlist id: 38, video_id: nil, player_id: 6, category_id: 87>, 
#<Playlist id: 39, video_id: 154, player_id: nil, category_id: 87>,
#<Playlist id: 40, video_id: 155, player_id: nil, category_id: 87>

但我们想要视频和玩家的笛卡尔产品:

#<Playlist id: 37, video_id: 154, player_id: 1, category_id: 87>, 
#<Playlist id: 38, video_id: 155, player_id: 6, category_id: 87>, 
#<Playlist id: 39, video_id: 154, player_id: 1, category_id: 87>,
#<Playlist id: 40, video_id: 155, player_id: 6, category_id: 87>

我们应该怎么做?

1 个答案:

答案 0 :(得分:0)

您必须定义自定义代码,而不是使用默认的ActiveRecord代码。

class Category
...
  def self.create_category(user, category_params)
    video_ids = category_params.delete(:video_ids)
    player_ids = category_params.delete(:player_ids)

    create(category_params.merge(:user_id => user.id)).tap do |cat|
      video_ids.each do |video_id|
        player_ids.each do |player_id|
          cat.playlists.create(video_id: video_id, player_id: player_id)
        end
      end
    end
  end
end

class CategoryController
...
  def create
    Category.create_category(current_user, category_params)
  end
end