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.