【问题标题】:In Rails, what is the difference using "has_many with belongs_to" vs "has_many with has_one"?在 Rails 中,使用“has_many with belongs_to”与“has_many with has_one”有什么区别?
【发布时间】:2010-09-15 02:45:51
【问题描述】:

例如,在

class Student < ActiveRecord::Base
  has_many :awards
end

class Awards < ActiveRecord::Base
  belongs_to :student
end

上面应该是正确的用法,但是如果我们使用呢

class Student < ActiveRecord::Base
  has_many :awards
end

class Awards < ActiveRecord::Base
  has_one :student
end

上面不是也可以将student.awards 作为一个Award 对象数组,将award.student 作为一个Student 对象,它是该奖项的获得者,所以工作方式与帖子顶部的方法相同?

【问题讨论】:

标签: ruby-on-rails activerecord belongs-to has-one


【解决方案1】:

has_one 用于一对一关系,而不是一对多关系。

正确使用has_one

class Student < ActiveRecord::Base
  has_one :id_card
end

class IdCard < ActiveRecord::Base
  belongs_to :student
end

【讨论】:

  • 重点是:带有belongs_to语句的类就是其表模式中带有外键的类。
【解决方案2】:

这两个例子并不等价。

has_manybelongs_to 在“多对一”关系中成对工作。

在数据库中,这看起来像:

**Students**
Name
Email
...

**Awards**
Name
student_id  <-- !IMPORTANT!
...

每个Student 都有很多奖项,因此has_many :awards 每个Award“属于”一个Student,因此是belongs_to :student

请注意,belongs_to 应用于具有外键 student_id 的表。这很重要。

好的 - 那么在存在“一对一”关系的情况下会发生什么?

如果每个学生只能获得一个奖项,那么数据库表可能看起来完全相同,但模型应该不能返回项目集合。

这就是我们需要has_one 声明的地方。在这种情况下,这将应用于Student 模型。为什么?因为关系在两个方向上是相同的,但 Active Record 需要知道在哪里可以找到外键。

如果数据库表是相反的,每个Student 都有一个award_id,那么Student 会得到belongs_toAward 会得到has_one

希望这说明清楚吗?

如果您使用自然语言,学生可能“属于”一个奖项,这似乎有点奇怪。但这就是 Rails 活动记录领域特定语言的编写方式。

当您查看与“has_many_and_belongs_to”的“多对多”关系时,听起来会更加不自然。这里有一个连接表,它位于您的主表之间,例如

students_awards
student_id
award_id

在这种情况下,StudentsAwards 表都没有外键,但两者都带有 has_many_and_belongs_to :other_table 声明。两个表都能够连接到另一个表的多行。每个Student 可以有多个Award。每个Award 可以应用于多个Students

has_one 声明在存在“一对一”关系且它所应用的表具有外键的情况下使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 2018-04-08
    • 2023-03-10
    相关资源
    最近更新 更多