【发布时间】:2011-04-18 01:25:30
【问题描述】:
belongs_to 和 has_one 有什么区别?
阅读 Ruby on Rails 指南对我没有帮助。
【问题讨论】:
标签: ruby-on-rails activerecord
belongs_to 和 has_one 有什么区别?
阅读 Ruby on Rails 指南对我没有帮助。
【问题讨论】:
标签: ruby-on-rails activerecord
我想补充一点,假设我们有以下模型关联。
class Author < ApplicationRecord
has_many :books
end
如果我们只写上面的关联,那么我们可以得到一个特定作者的所有书籍
@books = @author.books
但是,对于特定的书,我们无法获得相应的作者
@author = @book.author
要使上述代码正常工作,我们还需要向Book 模型添加关联,如下所示
class Book < ApplicationRecord
belongs_to :author
end
这会将方法“作者”添加到Book 模型。模式详情见guides
【讨论】:
has_one
other class 包含foreign key 时才应使用此方法。belongs_to
current class 包含foreign key 时才应使用此方法。【讨论】:
从简单的角度来看,belongs_to 优于 has_one,因为在 has_one 中,您必须将以下约束添加到具有外键的模型和表中以强制执行 has_one 关系:
validates :foreign_key, presence: true, uniqueness: true【讨论】:
has_one 和belongs_to 通常在某种意义上是相同的,它们指向另一个相关模型。 belongs_to 确保此模型已定义 foreign_key。
has_one 确保定义了另一个模型 has_foreign 键。
具体来说,relationship有两个侧面,一个是Owner,另一个是Belongings。如果只定义了has_one,我们可以得到它的Belongings,但不能从belongings 得到Owner。要追踪Owner,我们还需要在归属模型中定义belongs_to。
【讨论】:
这与外键所在的位置有关。
class Foo < AR:Base
end
belongs_to :bar,则 foos 表有一个 bar_id 列has_one :bar,则 bar 表有一个 foo_id 列在概念层面上,如果您的class A 与class B 有has_one 关系,那么class A 是class B 的父级,因此您的class B 将与class A 有belongs_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)
)
【讨论】:
Account 和 User 是很不幸的,因为一个帐户通常可以拥有许多用户。
他们基本上做同样的事情,唯一的区别是你在关系的哪一边。如果一个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是更详细的解释。
【讨论】:
Product belongs_to Shop 表示products 表有shop_id 列