ruby-on-rails belongs_to和have_one有什么区别?

sg3maiej  于 2023-05-30  发布在  Ruby
关注(0)|答案(7)|浏览(154)

belongs_tohas_one有什么区别?
阅读Ruby on Rails指南对我没有帮助。

dkqlctbz

dkqlctbz1#

他们本质上做同样的事情,唯一的区别是你站在关系的哪一边。如果一个User有一个Profile,那么在User类中你有has_one :profile,在Profile类中你有belongs_to :user。要确定谁“拥有”另一个对象,请查看外键的位置。我们可以说一个User“有”一个Profile,因为profiles表有一个user_id列。但是,如果users表上有一个名为profile_id的列,我们会说Profile有一个User,并且belongs_to/has_one位置将被交换。
here是更详细的解释。

zi8p0yeb

zi8p0yeb2#

关键在于外键的位置。

class Foo < AR:Base
end
  • 如果foo belongs_to :bar,则foos表有一个bar_id
  • 如果foo has_one :bar,则bars表具有foo_id

在概念层面上,如果class Aclass Bhas_one关系,那么class Aclass B的父节点,因此class B将与class Abelongs_to关系,因为它是class A的子节点。
两者都是1-1关系。区别主要在于外键的位置,它位于声明belongs_to关系的类的表中。

class User < ActiveRecord::Base
  # I reference an account.
  belongs_to :account
end

class Account < ActiveRecord::Base
  # One user references me.
  has_one :user
end

这些类的表可能如下所示:

CREATE TABLE users (
  id int(11) NOT NULL auto_increment,
  account_id int(11) default NULL,
  name varchar default NULL,
  PRIMARY KEY  (id)
)

CREATE TABLE accounts (
  id int(11) NOT NULL auto_increment,
  name varchar default NULL,
  PRIMARY KEY  (id)
)
xjreopfe

xjreopfe3#

has_onebelongs_to在指向其他相关模型的意义上通常是相同的。belongs_to确保此模型定义了foreign_keyhas_one确保定义了其他型号的has_foreign密钥。
更具体地说,relationship有两条边,一条是Owner,另一条是Belongings。如果只定义了has_one,我们可以得到它的Belongings,但不能从belongings得到Owner。为了跟踪Owner,我们需要在归属模型中定义belongs_to

c9qzyr3d

c9qzyr3d4#

我想补充的一点是,假设我们有以下模型关联。

class Author < ApplicationRecord
  has_many :books
end

如果我们只写上面的关联,那么我们就可以用

@books = @author.books

但是,对于一本特定的书,我们不能得到相应的作者

@author = @book.author

要使上面的代码工作,我们还需要向Book模型添加一个关联,如下所示

class Book < ApplicationRecord
  belongs_to :author
end

这将向Book模型添加方法'author'。有关模式的详细信息,请参见guides

tzcvj98z

tzcvj98z5#

has_one

  • 只有当other class包含foreign key时才应使用此方法。

belongs_to

  • 只有当current class包含foreign key时,才应使用此方法。
e37o9pze

e37o9pze6#

从简单的Angular 来看,belongs_tohas_one更好,因为在has_one中,您必须向具有外键的模型和表添加以下约束以强制has_one关系:

  • validates :foreign_key, presence: true, uniqueness: true
  • 在外键上添加数据库唯一索引。
piv4azn7

piv4azn77#

所有(所有?)其他答案已经指出,这都是关于外键存储的位置。
但这不一定是非常难忘的,所以这种思考方式可能会帮助你:

  • 如果你想记录你拥有的东西,你可以把你的名字写在你的财产上(比如把你的AirPods或iPhone刻上你的名字)
  • 但另一方面,你永远不会把iPhone或Air Pods的名字纹在身上。

因此,外键(对所有者的引用)总是在被拥有的东西(记录)上,而不是所有者的所有权记录。

相关问题