Las bases de datos relacionales contienen, como su nombre lo indica, datos que se relacionan entre sí. Estas relaciones pueden ser de distintos tipos (1:1, 1:N, N:N) y ActiveRecord nos permite definirlas a través de belongs_to
, has_many
, has_one
y has_and_belongs_to_many
.
De este modo, podemos encontrarnos con un objeto Article
que tiene las siguientes relaciones:
class Article < ApplicationRecord
belongs_to :user
has_many :comments
end
Gracias a esta definición de relaciones, podemos recuperar el usuario y comentarios asociados a un artículo de manera muy sencilla:
article = Article.find(1)
#<Article id: 1, user_id: 1>
article.user
# <User id: 1, first_name: "Fabián", last_name: "Show">
article.comments
#[
<Comment id: 1, article_id: 1, user_id: 10, body: "Excelente artículo">,
<Comment id: 2, article_id: 1, user_id: 12, body: "Gracias por compartir">
]
Con esas relaciones podemos hacer muchas más cosas, como recuperar objetos relacionados, eliminar y actualizar en masa, como también realizar consultas de manera más simple.
En esta oportunidad te voy a contar dos métodos muy útiles: where.associated
y where.missing
.
Associated
Con el método associated
se pueden recuperar los objetos que tienen datos del otro lado de una relación. Por ejemplo, podríamos recuperar los artículos que tienen al menos un comentario de la siguiente forma:
Article.where.associated(:comments)
Al ejecutar esa instrucción se estará traduciendo a la siguiente consulta SQL:
SELECT articles.*
FROM articles
INNER JOIN comments ON comments.article_id = articles.id
WHERE comments.id IS NOT NULL
Esta consulta retornará los artículos con uno o más comentarios.
Missing
En contraposición con associated
, ActiveRecord ofrece la posibilidad de recuperar los registros que no tengan datos del otro lado de una relación. Es decir, podríamos buscar los artículos que no tengan comentarios:
Article.where.missing(:comments)
Al ejecutar esa instrucción se estará traduciendo al siguiente SQL:
SELECT articles.*
FROM articles
LEFT OUTER JOIN comments ON comments.article_id = articles.id
WHERE comments.id IS NULL
Esta consulta retornará los artículos sin comentarios.
Gracias a estos dos métodos ganamos mucho en legibilidad y nos evitamos tener que armar un joins
combinado con un where
.
ActiveRecord está lleno de estas pequeñas joyitas que nos ayudan a que nuestro código sea más mantenible y claro. Te invito a mirar el resto en la documentación oficial.