¿Cuál es la diferencia entre belong_to y has_one?

Respuestas:

241

Básicamente hacen lo mismo, la única diferencia es de qué lado de la relación estás. Si a Usertiene un Profile, entonces en la Userclase que tendría has_one :profiley en la Profileclase que tendría belongs_to :user. Para determinar quién "tiene" el otro objeto, observe dónde está la clave externa. Podemos decir que un User"tiene" a Profileporque la profilestabla tiene una user_idcolumna. Sin embargo, si se llamara profile_ida una columna en la userstabla, diríamos que a Profiletiene un User, y las ubicaciones belong_to / has_one se intercambiarían.

Aquí hay una explicación más detallada.

ryeguy
fuente
ok tiene sentido, has_a es propiedad, mientras que a pertenece es más una relación.
Blankman
48
Para decirlo realmente corto: Product belongs_to Shopsignifica que la productstabla tiene una shop_idcolumna
Yo Ludke
@ryeguy, ¿qué pasa si se trata de una relación de autounión?
Arian Faurtosh
49

Se trata de dónde se encuentra la clave externa.

class Foo < AR:Base
end
  • Si foo belongs_to :bar, entonces la tabla foos tiene una bar_idcolumna
  • Si foo has_one :bar, entonces la tabla de barras tiene una foo_idcolumna

En el nivel conceptual, si class Atiene una has_onerelación con, class Bentonces class Aes el padre de, por lo class Btanto class B, tendrá una belongs_torelación con class Aél, ya que es hijo de class A.

Ambos expresan una relación 1-1. La diferencia es principalmente dónde colocar la clave foránea, que va sobre la mesa para la clase que declara la belongs_torelación.

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

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

Las tablas para estas clases podrían verse así:

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
fuente
Eso es más o menos lo mismo que la respuesta aceptada de hace dos años ya afirma.
matthias krull
11
Esta es una respuesta bastante mejor.
typeoneerror
El uso de Accounty Useren este ejemplo es lamentable ya que a menudo es el caso de que una cuenta puede tener muchos usuarios.
karmakaze
5

has_oney belongs_togeneralmente son iguales en un sentido que apuntan al otro modelo relacionado. belongs_toasegúrese de que este modelo tenga el foreign_keydefinido. has_onese asegura de que el otro modelohas_foreign clave del definida.

Para ser más específicos, hay dos lados de relationship, uno es el Ownery otro es Belongings. Si solo has_onese define, podemos obtener su Belongingspero no podemos obtener el Ownerde belongings. Para rastrear Ownernecesitamos definir el belongs_totambién en el modelo de pertenencia.

ilusionista
fuente
3

Una cosa adicional que quiero agregar es, supongamos que tenemos la siguiente asociación de modelos

class Author < ApplicationRecord has_many :books end

si solo escribimos la asociación anterior, podemos obtener todos los libros de un autor en particular,

@books = @author.books

Pero para un libro en particular no podemos obtener el autor correspondiente,

@author = @book.author

para que el código anterior funcione, también necesitamos agregar asociación al modelo de libro, como este

class Book < ApplicationRecord
  belongs_to :author
end

Esto agregará el método 'autor' al modelo de libro.
Para detalles del modo ver guías

Somesh Sharma
fuente
0

Desde el punto de vista de la simplicidad, belongs_toes mejor que has_oneporque en has_one, tendría que agregar las siguientes restricciones al modelo y la tabla que tiene la clave externa para hacer cumplir la has_onerelación:

  • validates :foreign_key, presence: true, uniqueness: true
  • agregue un índice único de base de datos en la clave externa.
Konyak
fuente