Respuestas:
Básicamente hacen lo mismo, la única diferencia es de qué lado de la relación estás. Si a User
tiene un Profile
, entonces en la User
clase que tendría has_one :profile
y en la Profile
clase 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 Profile
porque la profiles
tabla tiene una user_id
columna. Sin embargo, si se llamara profile_id
a una columna en la users
tabla, diríamos que a Profile
tiene un User
, y las ubicaciones belong_to / has_one se intercambiarían.
Aquí hay una explicación más detallada.
Product belongs_to Shop
significa que la products
tabla tiene una shop_id
columna
Se trata de dónde se encuentra la clave externa.
class Foo < AR:Base
end
belongs_to :bar
, entonces la tabla foos tiene una bar_id
columnahas_one :bar
, entonces la tabla de barras tiene una foo_id
columnaEn el nivel conceptual, si class A
tiene una has_one
relación con, class B
entonces class A
es el padre de, por lo class B
tanto class B
, tendrá una belongs_to
relació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_to
relació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)
)
Account
y User
en este ejemplo es lamentable ya que a menudo es el caso de que una cuenta puede tener muchos usuarios.
has_one
y belongs_to
generalmente son iguales en un sentido que apuntan al otro modelo relacionado. belongs_to
asegúrese de que este modelo tenga el foreign_key
definido.
has_one
se asegura de que el otro modelohas_foreign
clave del definida.
Para ser más específicos, hay dos lados de relationship
, uno es el Owner
y otro es Belongings
. Si solo has_one
se define, podemos obtener su Belongings
pero no podemos obtener el Owner
de belongings
. Para rastrear Owner
necesitamos definir el belongs_to
también en el modelo de pertenencia.
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
Desde el punto de vista de la simplicidad, belongs_to
es mejor que has_one
porque 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_one
relación:
validates :foreign_key, presence: true, uniqueness: true