什么时候应该在Rails中使用“has_many:through”关系?
我想了解什么has_many :through
是什么时候使用它(以及如何)。 但是,我没有得到它。 我正在阅读Beginning Rails 3,我尝试了谷歌search,但我无法理解。
假设你有两个模型: User
和Group
。
如果你想让用户属于组,那么你可以做这样的事情:
class Group < ActiveRecord::Base has_many :users end class User < ActiveRecord::Base belongs_to :group end
如果你想跟踪关联的其他元数据呢? 例如,当用户join该组时,或者用户的angular色在该组中是什么?
这是您将关联设置为第一类对象的地方:
class GroupMembership < ActiveRecord::Base belongs_to :user belongs_to :group # has attributes for date_joined and role end
这将引入一个新表,并从用户表中删除group_id
列。
这个代码的问题是,你必须更新每个你使用用户类的地方,并改变它:
user.groups.first.name # becomes user.group_memberships.first.group.name
这种types的代码很糟糕,而且会导致这样的改变。
has_many :through
给你最好的两个世界:
class User < ActiveRecord::Base has_many :groups, :through => :group_memberships # Edit :needs to be plural same as the has_many relationship has_many :group_memberships end
现在你可以像正常的has_many
一样对待它,但是当你需要的时候可以获得关联模型的好处。
请注意,你也可以用has_one
来做到这一点。
编辑:可以轻松地将用户添加到组中
def add_group(group, role = "member") self.group_associations.build(:group => group, :role => role) end
假设你有这些模型:
Car Engine Piston
汽车has_one :engine
一个引擎belongs_to :car
引擎has_many :pistons
活塞belongs_to :engine
汽车has_many :pistons, through: :engine
活塞has_one :car, through: :engine
基本上,你正在委托一个模型的关系到另一个模型,所以不必打电话给car.engine.pistons
,你可以做car.pistons
ActiveRecord连接表
has_many :through
和has_and_belongs_to_many
关系通过连接表起作用, 连接表是一个表示其他表之间关系的中间表。 与JOIN查询不同,数据实际上存储在一个表中。
实际差异
使用has_and_belongs_to_many
,您不需要主键,而是通过ActiveRecord关系访问logging,而不是通过ActiveRecord模型。 当您想要将两个模型链接成多对多的关系时,通常使用HABTM。
当您想要与连接表交互作为Rails模型时,您可以使用has_many :through
关系,并使用主键和将自定义列添加到连接数据的function。 后者对于与连接行相关的数据尤为重要,但并不属于相关模型 – 例如,存储从连接行中的字段派生的计算值。
也可以看看
在“活动logging协会指南”中 ,build议如下:
最简单的经验法则是,如果您需要将关系模型作为一个独立的实体来使用,您应该build立一个has_many:through关系。 如果你不需要对关系模型做任何事情,build立一个has_and_belongs_to_many关系可能会更简单(尽pipe你需要记住在数据库中创build连接表)。
如果您需要validation,callback或join模型的额外属性,则应该使用has_many:through。
我会build议通过
http://guides.rubyonrails.org/association_basics.html
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
这些是官方的轨道文件,并有很好的文件。
也http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many 。
这里还有ryan bates的截屏video:http: //railscasts.com/episodes/47-two-many-to-many
阅读 Rails教程和has_many的 这一部分:通过导轨部分 。
这篇文章应该解释你何时使用has_many :through
。