【问题标题】:Is has_many still necessary when has_many through exists?当 has_many through 存在时,has_many 是否仍然必要?
【发布时间】:2018-03-11 01:45:48
【问题描述】:

我觉得这是一个超级简单的问题,但我在任何地方都找不到答案!

问题:

如果我之前有一个类似这样的 has_many 关系:has_many :wikis,如果以后我创建一个类似下面的 has_many through 关系,我是否保留这个关系?

has_many :collaborators
has_many :wikis, through: :collaborators

这一切都在我的用户模型中。

背景:

在我的 rails 应用程序中,我有一个用户模型和一个 Wiki 模型。我只是让用户能够在私人 wiki 上进行协作,所以我迁移了一个 Collaborator 模型,然后迈出了通过关系创建 has_many 的步骤。我不确定在输入has_many :wikis, through: :collaborators 之后是否还需要has_many :wikis

我感到困惑的原因是因为用户应该仍然能够在没有合作者的情况下创建 wiki,而且我不确定 has_many through 关系在后台是如何运作的。

最初我只有 User 和 Wiki 的一对多关系。

# User model
class User < ApplicationRecord
  ...    
  has_many :wikis # should I delete this?
  has_many :collaborators
  has_many :wikis, through: :collaborators
  ...
end

# Collaborator model
class Collaborator < ApplicationRecord
  belongs_to :user
  belongs_to :wiki
end

# Wiki model
class Wiki < ApplicationRecord
  belongs_to :user

  has_many :collaborators, dependent: :destroy
  has_many :users, through: :collaborators
  ...
end

【问题讨论】:

  • 我会添加两个不同的关系,has_many :created_wikishas_many :collaborated_wikis。此外,为了更好地维护创建 wiki 的用户,应在创建 wiki 时添加为协作者。因此,用户可以知道他创建了哪些 wiki,以及他可以为哪些 wiki 做出贡献。

标签: ruby-on-rails has-many-through


【解决方案1】:

当 has_many through 存在时,has_many 还需要吗?

has_many 像你的模特一样存在has_many through 时没有必要

has_many :wikis # should I delete this?
has_many :collaborators
has_many :wikis, through: :collaborators

我应该删除这个吗?

是的,你可以删除这个,你不需要这个和belongs_to一样

The has_many Association

has_many 关联表示与另一个模型的一对多连接。您经常会在 belongs_to 关联的“另一边”找到此关联。这种关联表明模型的每个实例都有另一个模型的零个或多个实例。例如,在包含作者和书籍的应用程序中,作者模型可以这样声明:

The has_many :through Association

has_many :through 关联通常用于与另一个模型建立多对多连接。这种关联表明声明模型可以通过第三个模型与另一个模型的零个或多个实例匹配。例如,考虑一个患者预约看医生的医疗实践。相关的关联声明可能如下所示:

class Physician < ApplicationRecord
  has_many :appointments
  has_many :patients, through: :appointments
end

class Appointment < ApplicationRecord
  belongs_to :physician
  belongs_to :patient
end

class Patient < ApplicationRecord
  has_many :appointments
  has_many :physicians, through: :appointments
end

你可以只使用has_many关联而不使用has_many :through,但这是一对多,而不是多对多

  • has_many 关联(没有has_many :through)是与另一个模型的一对多连接
  • has_many :through 关联与另一个模型建立了多对多连接

更新

看,一个医生可能有很多病人,另一方面,一个病人可能有很多医生,如果你使用has_many关联而不通过病人那么这称为one-to-many关联,这意味着一个医生有很多病人,另一方面,一个患者属于一个医生,现在关联看起来像这样

class Physician < ApplicationRecord
  has_many :patients
end

class Patient < ApplicationRecord
  belongs_to :physician
end

更新 2

has_many通过标准格式你的模型编辑后

# User model
class User < ApplicationRecord
  ...    
  has_many :collaborators
  has_many :wikis, through: :collaborators
  ...
end

# Collaborator model
class Collaborator < ApplicationRecord
  belongs_to :user
  belongs_to :wiki
end

# Wiki model
class Wiki < ApplicationRecord
  has_many :collaborators, dependent: :destroy
  has_many :users, through: :collaborators
  ...
end

【讨论】:

  • 对不起,我阅读了文档,但我仍然不完全理解。所以你是说多对多连接使一对多连接变得多余?
  • 使用上图,如果我想要一个没有预约的医患关系,我是否应该包含has_manyhas_many through
  • 不,你不需要has_many through当一对多的关系时,查看更新部分的答案@DamianRivas
  • 你误会我了。我完全理解belongs_to 和has_many。我刚刚创建了协作者,现在想通过实现 has_many。我将删除原来的 has_many 并留意错误。
  • 不,我不需要像wikis 表上的父级索引,您需要foreign_key。为此,您需要完全遵循此主题guides.rubyonrails.org/…一对多
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-17
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
  • 2019-03-04
  • 2014-09-01
  • 2011-07-24
相关资源
最近更新 更多