8

例如,在

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 对象,因此与帖子顶部的方法的工作方式相同吗?

4

2 回答 2

8

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

正确使用has_one

class Student < ActiveRecord::Base
  has_one :id_card
end

class IdCard < ActiveRecord::Base
  belongs_to :student
end
于 2010-09-15T03:05:43.927 回答
3

这两个例子是不等价的。

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_to并且Award将获得has_one.

希望清楚吗?

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

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

students_awards
student_id
award_id

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

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

于 2015-02-10T15:04:01.470 回答