Jaka jest różnica między should_to i has_one?

Odpowiedzi:

241

Zasadniczo robią to samo, jedyną różnicą jest to, po której stronie związku jesteś. Jeśli a Userma Profile, to w Userklasie, którą byś miał, has_one :profileiw Profileklasie, którą miałbyś belongs_to :user. Aby określić, kto „ma” inny obiekt, spójrz, gdzie jest klucz obcy. Można powiedzieć, że a User„ma” a, Profileponieważ profilestabela ma user_idkolumnę. Gdyby jednak profile_idw userstabeli była wywołana kolumna , powiedzielibyśmy, że a Profilema a User, a lokalizacje należą do / has_one zostałyby zamienione.

tutaj jest bardziej szczegółowe wyjaśnienie.

ryeguy
źródło
ok ma sens, has_a jest własnością, podczas gdy przynależność jest bardziej relacją.
Blankman,
48
Krótko mówiąc, Product belongs_to Shopoznacza to, że productstabela ma shop_idkolumnę
Yo Ludke
@ryeguy, a co jeśli jest to relacja samodzielnego dołączenia?
Arian Faurtosh
49

Chodzi o to, gdzie znajduje się klucz obcy.

class Foo < AR:Base
end
  • Jeśli foo belongs_to :bar , to tabela foos ma bar_idkolumnę
  • Jeśli foo has_one :bar, to tabela słupków mafoo_id kolumnę

Na poziomie koncepcyjnym, jeśli class Ama has_onezwiązek z class Bczym class Ajest rodzicem class Bstąd twój class Bbędzie mieć belongs_tozwiązek zclass A ponieważ jest dzieckiemclass A .

Obie wyrażają zależność 1-1. Różnica polega głównie na tym, gdzie umieścić klucz obcy, który trafia na tabelę dla klasy deklarującej belongs_tozwiązek.

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

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

Tabele dla tych zajęć mogłyby wyglądać mniej więcej tak:

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)
)
Chandan Kumar Mallik
źródło
To prawie to samo, co przyjęta odpowiedź sprzed dwóch lat.
matthias krull
11
To znacznie lepsza odpowiedź.
typoneerror
Użycie Accounti Userw tym przykładzie jest niefortunne, ponieważ często zdarza się, że konto może mieć wielu użytkowników.
karmakaze
5

has_onei belongs_toogólnie są takie same w tym sensie, że wskazują na inny powiązany model. belongs_toupewnij się, że ten model ma foreign_keyzdefiniowane. has_oneupewnia się, że has_foreignzdefiniowano inny klucz modelu .

Mówiąc dokładniej, istnieją dwie strony relationship, jedna jest Ownerdruga, a druga jest Belongings. Jeśli tylko has_onejest zdefiniowane, możemy uzyskać jego, Belongingsale nie możemy uzyskać Ownerz belongings. Aby prześledzić Owner, musimy zdefiniować belongs_torównież w przynależnym modelu.

iluzjonista
źródło
3

Jedną dodatkową rzeczą, którą chcę dodać, jest: Załóżmy, że mamy następujące skojarzenia modeli

class Author < ApplicationRecord has_many :books end

jeśli napiszemy tylko powyższe skojarzenie, możemy otrzymać wszystkie książki danego autora przez,

@books = @author.books

Ale w przypadku konkretnej książki nie możemy znaleźć odpowiedniego autora,

@author = @book.author

aby powyższy kod działał, musimy dodać skojarzenie również do modelu Book, w ten sposób

class Book < ApplicationRecord
  belongs_to :author
end

Spowoduje to dodanie metody „autor” do modelu książki.
Szczegółowe informacje na temat trybu można znaleźć w przewodnikach

Somesh Sharma
źródło
0

Z prostego punktu widzenia belongs_tojest lepsze niż has_oneponieważ w programie has_onenależałoby dodać następujące ograniczenia do modelu i tabeli, które mają klucz obcy, aby wymusić has_onerelację:

  • validates :foreign_key, presence: true, uniqueness: true
  • dodać unikalny indeks bazy danych do klucza obcego.
konyak
źródło