在Rails中创建多对多关系

时间:2013-02-07 16:37:01

标签: ruby-on-rails ruby-on-rails-3

所以我是Rails n00b,我想创建一个“收藏夹”关系,以便用户可以拥有许多喜欢的项目。我不完全确定如何做到这一点,这就是我要尝试的方式,但我不确定这是否是一个很好的做法:

class User < ActiveRecord::Base
 has_many :favorites
 //other code
end

class Favorite < ActiveRecord::Base
 belong_to :user
 has_one :item
end

class Item < ActiveRecord::Base
 belongs_to :item
end

这是一个很好的方法吗?我应该使用has_and_belongs_to_many吗? 我特别关注以下场景:假设用户有100个最喜欢的项目。 当我做User.find(id)时,我还会检索100个收藏夹和100个项目吗?

如果它很重要:ruby版本1.9.3,rails版本3.2.11

3 个答案:

答案 0 :(得分:3)

你能试试has_many => :through吗?

class User < ActiveRecord::Base
 has_many :favorites
 has_many :items, :through => :favorites
 //other code
end

答案 1 :(得分:2)

在你的情况下has_many:通过绝对是要走的路。我建议阅读:http://guides.rubyonrails.org/association_basics.html

对您的问题特别感兴趣:

2.8在has_many:through和has_and_belongs_to_many

之间选择
  

Rails提供了两种不同的方式来声明模型之间的多对多关系。更简单的方法是使用has_and_belongs_to_many,它允许您直接建立关联:

class Assembly < ActiveRecord::Base
  has_and_belongs_to_many :parts
end

class Part < ActiveRecord::Base
  has_and_belongs_to_many :assemblies
end
  

声明多对多关系的第二种方法是使用has_many:through。这通过连接模型间接地建立了关联:

class Assembly < ActiveRecord::Base
  has_many :manifests
  has_many :parts, :through => :manifests
end

class Manifest < ActiveRecord::Base
  belongs_to :assembly
  belongs_to :part
end

class Part < ActiveRecord::Base
  has_many :manifests
  has_many :assemblies, :through => :manifests
end
  

最简单的经验法则是,如果需要将关系模型作为独立实体使用,则应设置has_many:through关系。如果您不需要对关系模型执行任何操作,则设置has_and_belongs_to_many关系可能更简单(尽管您需要记住在数据库中创建连接表)。

     

如果您需要在连接模型上进行验证,回调或额外属性,则应使用has_many:through。

答案 2 :(得分:0)

这比使用has_and_belongs_to_many更好。

  

当我做User.find(id)时,我也会检索100个收藏夹   和100项?

没有。你只需要获得用户对象。

<强>更新 调用User.include(:favourites, :items).find(id)会让你加入表,以防你想从用户对象中多次调用items表。