Ответы:
По сути, они делают то же самое, единственная разница в том, на какой стороне отношений вы находитесь. Если a Userимеет a Profile, то в Userклассе, который у вас есть, has_one :profileи в Profileклассе, который у вас будет belongs_to :user. Чтобы определить, кто «имеет» другой объект, посмотрите, где находится внешний ключ. Мы можем сказать, что User«имеет» a, Profileпотому что в profilesтаблице есть user_idстолбец. Однако если бы profile_idв usersтаблице был вызван столбец , мы бы сказали, что a Profileимеет a User, и местоположения own_to / has_one поменяется местами.
вот более подробное объяснение.
Product belongs_to Shopозначает, что в productsтаблице есть shop_idстолбец
Это о том, где находится внешний ключ.
class Foo < AR:Base
end
belongs_to :bar, то в таблице foos есть bar_idстолбецhas_one :bar, то таблица баров имеет foo_idстолбецНа концептуальном уровне, если у вас class Aесть has_oneотношения с, class Bто class Aвы являетесь родителем, class Bследовательно, у вас class Bбудут belongs_toотношения с ним, class Aпоскольку он является потомком 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в этом примере является неудачным, поскольку часто бывает, что у учетной записи может быть много пользователей.
has_oneи, belongs_toкак правило, одинаковы в том смысле, что они указывают на другую связанную модель. belongs_toубедитесь, что эта модель имеет foreign_keyопределенную
has_oneгарантирует, что другой has_foreignключ модели определен.
Чтобы быть более конкретным, есть две стороны relationship, одна из которых Ownerи другая Belongings. Если has_oneопределено только, мы можем получить его, Belongingsно не можем получить Ownerиз belongings. Чтобы отследить, Ownerнам нужно определить belongs_toтакже и принадлежащую модель.
Еще одна вещь, которую я хочу добавить: предположим, у нас есть следующие ассоциации моделей
class Author < ApplicationRecord
has_many :books
end
если мы только напишем вышеупомянутую ассоциацию, то мы можем получить все книги определенного автора,
@books = @author.books
Но для конкретной книги мы не можем получить соответствующего автора,
@author = @book.author
чтобы приведенный выше код работал, нам нужно добавить ассоциацию в модель Book, например, так:
class Book < ApplicationRecord
belongs_to :author
end
Это добавит метод 'author' в модель Book.
Подробнее о режиме см. Руководства
С точки зрения простоты, belongs_toэто лучше, чем has_oneпотому has_one, что в , вы должны добавить следующие ограничения к модели и таблице, имеющей внешний ключ, для обеспечения has_oneвзаимосвязи:
validates :foreign_key, presence: true, uniqueness: true