ASOCIACIONES
belongs_to (PERTENECE A)
Especifico para relaciones one-to-one (1:1) con otra clase. Este método solo puede ser usado si esta clase contiene la clave externa. Si la otra clase contiene la clave externa deberá usar has_one en su lugar.
has_one (TIENE UN)
Especifico para relaciones one-to-one (1:1) con otra clase. Este método este método solo puede ser usado si la otra clase contiene la clave externa. Si la clase actual contiene la clave externa deberá usar belongs_to en su lugar.
** ¿ Es una asociación belongs_to ó has_one?
Ambos expresan una relación (1:1). La diferencia es donde colocar la clave foránea, que va en la tabla de la clase que declaro la asociación belongs_to.
class User < ActiveRecord::Base belongs_to :account end class Account < ActiveRecord::Base has_one :user end
CREATE TABLE users ( id bigint NOT NULL auto_increment, account_id bigint default NULL, #<----Foreign Key name varchar default NULL, PRIMARY KEY (id) ) CREATE TABLE accounts ( id bigint NOT NULL auto_increment, name varchar default NULL, PRIMARY KEY (id) )
has_many (TIENE MUCHOS)
Especifica una asociación de uno a muchos. (1:N). La clase referenciada debe implementar belongs_to.
has_and_belongs_to_many (TIENE Y PERTENECE A MUCHAS)
Especifica una asociación de muchos a muchos (N:M) con otra clase. Estas clases se asocian en una tabla intermedia. Ambas clases deben usar has_and_belongs_to_many para referenciar a la otra clase.
RELACIONES
RELACIÓN ONE TO ONE (1:1)
(**Ejemplo que un Usuario solo puede tener una Dirección Postal)
1.- Creamos modelos (usuario, address)
bin/rails g model Usuario name:string
bin/rails g model Address street:string
2.- Añadimos la columna Usuario (has_one) a la Dirección (belongs_to)
bin/rails generate migration AddUsuarioToAddresses usuario:references
Se crea la siguiente migración:
class AddUsuarioToAddresses < ActiveRecord::Migration[5.0] def change add_reference :addresses, :usuario, foreign_key: true end end
3.- Ejecutamos la migración en la BBDD:
rake db:migrate
4.- ActiveRecord no sabe de la asociación de los dos modelos, Tenemos que añadir los atributos has_one y belongs_to:
class Usuario < ApplicationRecord has_one :address end class Address < ApplicationRecord belongs_to :usuario end
5.- Ahora se podría añadir una Dirección a un Usuario:
usuarioEjemplo = Usuario.new(name:"Pepe") direccionEjemplo = Address.new(street:"Calle Ejemplo") #Ambas hacen la asociacion # direccionEjemplo.usuario = usuarioEjemplo # usuarioEjemplo.address = direccionEjemplo usuarioEjemplo.save
Y buscar la Dirección que esta asociada al ultimo Usuario guardado:
Usuario.last.address
RELACIÓN ONE TO MANY(1:N)
1.- Creamos modelos (comentario,post)
bin/rails g model Comentario text:string
bin/rails g model Post title:string
2.- Añadimos la columna Post (has_many) a los Comentarios (belongs_to):
bin/rails generate migration AddPostToComentarios post:references
Se crea la siguiente migración:
class AddPostToComentarios < ActiveRecord::Migration[5.0] def change add_reference :comentarios, :post, foreign_key: true end end
3.- Ejecutamos la migración en la BBDD:
rake db:migrate
4.- ActiveRecord no sabe de la asociación de los dos modelos, Tenemos que añadir los atributos has_many y belongs_to:
class Post < ApplicationRecord has_many :comentarios end class Comentario < ApplicationRecord belongs_to :post end
Ahora se podría añadir un Comentario a un Post:
comentario1 = Comentario.new comentario1.text = "Comentario de prueba" post1 = Post.new post1.title = "Primer Post" post1.comentarios << comentario1 post1.save
Y buscar Comentarios que pertenezcan a un Post:
Post.last.comentarios # [Array de Comentarios]
RELACIÓN MANY TO MANY (N:M)
1.- Creamos modelos (usuario, foro)
bin/rails g model User name:string
bin/rails g model Forum name:string
2.- Creamos la tabla JOIN
bin/rails g migration CreateJoinTableUsersForums users forums
Se crea la siguiente migración, que tendremos que descomentar:
class CreateJoinTableUsersForums < ActiveRecord::Migration[5.0] def change create_join_table :users, :forums do |t| t.index [:user_id, :forum_id] #Descomentar esto t.index [:forum_id, :user_id] #Descomentar esto end end end
3.- Ejecutamos la migración en la BBDD:
rake db:migrate
4.- ActiveRecord no sabe usar la tabla JOIN para asociar los dos modelos, Tenemos que añadir el atributo has_and_belongs_to_many a ambos modelos.
class User < ApplicationRecord has_and_belongs_to_many :forums end class Forum < ApplicationRecord has_and_belongs_to_many :users end
Ahora se podría añadir un Foro a un Usuario
user.forums << Forum.find_by(name: "Ruby")
Y buscar Usuarios que pertenezcan a un Foro:
Forum.find_by(name: "Ruby").users