Was ist der Unterschied zwischen Gehört zu und Habe?


Antworten:


241

Sie machen im Wesentlichen dasselbe, der einzige Unterschied ist, auf welcher Seite der Beziehung Sie sich befinden. Wenn a ein Userhat Profile, dann in der UserKlasse, die Sie haben würden, has_one :profileund in der ProfileKlasse, die Sie haben würden belongs_to :user. Um festzustellen, wer das andere Objekt "hat", überprüfen Sie, wo sich der Fremdschlüssel befindet. Wir können sagen, dass ein User"hat" ein, Profileweil die profilesTabelle eine user_idSpalte hat. Wenn jedoch eine Spalte profile_idin der usersTabelle aufgerufen würde, würden wir sagen, dass a eine Profilehat Userund die Positionen "Gehört zu / Hat_one" vertauscht würden.

Hier ist eine detailliertere Erklärung.


ok macht Sinn, has_a ist Eigenschaft, während a eher eine Beziehung ist.
Blankman

47
Product belongs_to Shopproductsshop_id
Um

@ryeguy, was ist, wenn dies eine Self-Join-Beziehung ist?
Arian Faurtosh

49

Es geht darum, wo sich der Fremdschlüssel befindet.

class Foo < AR:Base
end
  • Wenn foo belongs_to :bar, dann hat der foos Tisch einebar_id Spalte
  • Wenn foo has_one :bar, dann hat die Balkentabelle eine foo_idSpalte

Auf der konzeptionellen Ebene, wenn Ihr class Aeine hat has_oneBeziehung mit class Bdann class Aist das Elternteil class Bdamit Ihr class Beine haben belongs_toBeziehung , class Ada es das Kindclass A .

Beide drücken eine 1-1 Beziehung aus. Der Unterschied besteht hauptsächlich darin, wo der Fremdschlüssel platziert werden soll, der für die Klasse, die die belongs_toBeziehung deklariert, auf dem Tisch liegt .

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

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

Die Tabellen für diese Klassen könnten ungefähr so ​​aussehen:

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)
)

Das ist so ziemlich das Gleiche, wie die akzeptierte Antwort von vor zwei Jahren bereits besagt.
Matthias Krull

11
Dies ist so ziemlich eine bessere Antwort.
Typoneerror

Die Verwendung von Accountund Userin diesem Beispiel ist unglücklich, da ein Konto häufig viele Benutzer haben kann.
Karmakaze

5

has_oneund belongs_tosind im Allgemeinen in dem Sinne gleich, dass sie auf das andere verwandte Modell verweisen. belongs_toStellen Sie sicher, dass dieses Modell das foreign_keydefinierte hat. has_onestellt sicher, dass der andere Modellschlüssel has_foreigndefiniert ist.

Genauer gesagt gibt es zwei Seiten: die relationshipeine ist die Ownerandere und die andere Belongings. Wenn nur has_onedefiniert ist, können wir seine bekommen, Belongingsaber nicht die Ownervon der belongings. Um das zu verfolgen Owner, müssen wir das belongs_toauch im zugehörigen Modell definieren.


3

Eine zusätzliche Sache, die ich hinzufügen möchte, ist: Angenommen, wir haben folgende Modellzuordnung

class Author < ApplicationRecord has_many :books end

Wenn wir nur die obige Assoziation schreiben, können wir alle Bücher eines bestimmten Autors erhalten von,

@books = @author.books

Aber für ein bestimmtes Buch können wir den entsprechenden Autor nicht von bekommen,

@author = @book.author

Damit der obige Code funktioniert, müssen wir auch dem Buchmodell eine Zuordnung hinzufügen

class Book < ApplicationRecord
  belongs_to :author
end

Dadurch wird dem Buchmodell die Methode 'author' hinzugefügt.
Einzelheiten zum Modus finden Sie in den Anleitungen


0

Aus Sicht der Einfachheit belongs_toist dies besser als has_oneweil has_oneSie dem Modell und der Tabelle, die den Fremdschlüssel zum Erzwingen der has_oneBeziehung enthalten , die folgenden Einschränkungen hinzufügen müssten :

  • validates :foreign_key, presence: true, uniqueness: true
  • Fügen Sie einen eindeutigen Datenbankindex für den Fremdschlüssel hinzu.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.