¿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.


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

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.


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


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.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.