Luc*_*uke 116 activerecord ruby-on-rails ruby-on-rails-3
我试图了解什么has_many :through是什么以及何时使用它(以及如何使用).但是,我没有得到它.我正在阅读Beginning Rails 3,我尝试使用谷歌搜索,但我无法理解.
cpu*_*y83 193
假设你有这些模型:
Car
Engine
Piston
Run Code Online (Sandbox Code Playgroud)
汽车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
Ben*_*man 171
假设你有两个型号: User和Group.
如果您想让用户属于组,那么您可以执行以下操作:
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
Run Code Online (Sandbox Code Playgroud)
如果您想跟踪关联周围的其他元数据,该怎么办?例如,当用户加入群组时,或者用户角色在群组中的位置?
这是您将关联作为第一类对象的地方:
class GroupMembership < ActiveRecord::Base
belongs_to :user
belongs_to :group
# has attributes for date_joined and role
end
Run Code Online (Sandbox Code Playgroud)
这引入了一个新表,并group_id从用户表中删除了该列.
此代码的问题在于您必须更新使用用户类的其他位置并更改它:
user.groups.first.name
# becomes
user.group_memberships.first.group.name
Run Code Online (Sandbox Code Playgroud)
这种类型的代码很糟糕,它使得引入这样的变化变得很痛苦.
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
Run Code Online (Sandbox Code Playgroud)
现在,您可以像平常一样对待它has_many,但在需要时可以获得关联模型的好处.
请注意,您也可以这样做has_one.
编辑:轻松将用户添加到组中
def add_group(group, role = "member")
self.group_associations.build(:group => group, :role => role)
end
Run Code Online (Sandbox Code Playgroud)
Tod*_*obs 17
has_many :through和has_and_belongs_to_manyrelationship通过连接表来起作用,连接表是一个表示其他表之间关系的中间表.与JOIN查询不同,数据实际存储在表中.
使用时has_and_belongs_to_many,您不需要主键,而是通过ActiveRecord关系而不是通过ActiveRecord模型访问记录.当您想要链接具有多对多关系的两个模型时,通常使用HABTM.
has_many :through当您想要作为Rails模型与连接表进行交互时,可以使用关系,包括主键以及向已连接数据添加自定义列的功能.后者对于与连接行相关的数据尤为重要,但并不真正属于相关模型 - 例如,存储从连接行中的字段派生的计算值.
在"活跃记录协会指南"中,建议如下:
最简单的经验法则是,如果需要将关系模型作为独立实体使用,则应设置has_many:through关系.如果您不需要对关系模型执行任何操作,则设置has_and_belongs_to_many关系可能更简单(尽管您需要记住在数据库中创建连接表).
如果需要在连接模型上进行验证,回调或额外属性,则应使用has_many:through.
| 归档时间: |
|
| 查看次数: |
74864 次 |
| 最近记录: |