Яка різниця між last_to та has_one?


Відповіді:


241

Вони по суті роблять те саме, різниця лише в тому, на якій стороні відносин ви перебуваєте. Якщо у a Userє Profile, то в Userкласі, який ви мали б, has_one :profileі в Profileкласі, який ви мали б belongs_to :user. Щоб визначити, хто "має" інший об'єкт, подивіться, де знаходиться зовнішній ключ. Можна сказати, що User"має" a, Profileоскільки в profilesтаблиці є user_idстовпець. Якби profile_idу usersтаблиці був стовпчик, який називається , ми б сказали, що a Profileмає a User, а місця значень pripada_to / has_one будуть замінені.

ось більш детальне пояснення.


ОК має сенс, has_a - це властивість, тоді як pripada - це більше відношення.
Бланкмен

48
Так би мовити, це дуже коротко: таблиця Product belongs_to Shopзасобів productsмає shop_idколонку
Йо Людке

@ryeguy, а як бути, якщо це стосунки самозалучення?
Аріан Фауртош

49

Йдеться про те, де сидить іноземний ключ.

class Foo < AR:Base
end
  • Якщо foo belongs_to :bar, то в таблиці foos є bar_idстовпець
  • Якщо foo 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)
)

Це майже однакова прийнята відповідь від двох років тому.
matthias krull

11
Це набагато краща відповідь.
typeoneerror

Використання Accountта Userв цьому прикладі прикро, оскільки часто трапляється так, що в обліковому записі може бути багато користувачів.
karmakaze

5

has_oneі, belongs_toяк правило, однакові в тому сенсі, що вони вказують на іншу споріднену модель. belongs_toпереконайтесь, що ця модель foreign_keyвизначена. has_oneпереконує, що інша модельhas_foreign ключ .

Якщо бути більш конкретним, то є дві сторони relationship, одна є, Ownerа інша є Belongings. Якщо тільки has_oneвизначено, ми можемо отримати його, Belongingsале не можемо отримати його Ownerвід belongings. Щоб простежити, Ownerнам потрібно визначити belongs_toтакож відповідну модель.


3

Ще одне, що я хочу додати, це, припустимо, у нас є наступні асоціації моделей

class Author < ApplicationRecord has_many :books end

якщо ми пишемо тільки вищезгадану асоціацію, то ми можемо отримати всі книги конкретного автора,

@books = @author.books

Але для певної книги ми не можемо знайти відповідного автора,

@author = @book.author

щоб зробити роботу вищезгаданого коду нам потрібно також додати асоціацію до моделі Book, як це

class Book < ApplicationRecord
  belongs_to :author
end

Це додасть метод "автор" до моделі Book.
Детальну інформацію про режим див. У посібниках


0

З точки зору простоти, belongs_toце краще, ніж has_oneчерез те has_one, що вам доведеться додати наступні обмеження до моделі та таблиці, у яких є закордонний ключ для забезпечення has_oneвідносин:

  • validates :foreign_key, presence: true, uniqueness: true
  • додати унікальний індекс бази даних на зовнішньому ключі.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.