代码之家  ›  专栏  ›  技术社区  ›  nonopolarity

在rails中,使用“has戆many with belongs戆to”与“has戆many with has戆one”有什么区别?

  •  5
  • nonopolarity  · 技术社区  · 14 年前

    例如,在

    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.student 作为一个学生的对象,哪一个是获奖者,所以工作的方式和文章顶部的方法一样?

    2 回复  |  直到 14 年前
        1
  •  7
  •   Mischa    14 年前

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

    正确使用 有一个 :

    class Student < ActiveRecord::Base
      has_one :id_card
    end
    
    class IdCard < ActiveRecord::Base
      belongs_to :student
    end
    
        2
  •  1
  •   Richard Washington    9 年前

    这两个例子并不相等。

    has_many belongs_to 在有“多对一”关系的地方成对工作。

    在数据库中,如下所示:

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

    Student 因此获得了很多奖项 has_many :awards Award “属于”A 学生 因此 belongs_to :student

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

    好吧-如果是“一对一”的关系怎么办?

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

    这就是我们需要的 has_one 宣言。这将适用于 学生 本例中的模型。为什么?因为两个方向上的关系都是相同的,但是活动记录需要知道在哪里可以找到外键。

    如果数据库表与每个 学生 有一个 award_id 然后 学生 会得到 属于 以及 会得到 有一个 .

    希望这能说明问题?

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

    当你看到“多对多”的关系时,它会变得更加不自然。这里有一个连接表,在主表之间

    students_awards
    student_id
    award_id
    

    在这种情况下 Students 也不是 Awards 桌子上有一把外键,但两把都带着 has_many_and_belongs_to :other_table 宣言。两个表都可以连接到另一个表的多行。各 学生 可以有多个 . 各 可以应用于许多 学生 .

    这个 有一个 声明是 只有 用于存在“一对一”关系且应用于该关系的表 有外键。