Uma das estruturas mais poderosas, e complexas do Rails é sem dúvida o Active Record. Em poucos minutos podemos criar um novo model e sua tabela para armazenar os dados. É normal que na hora de declarar relacionamentos, duvidas acabem surgindo. Então, eu decidi escrever este artigo para ajudar você a fazer uso desse recurso, quase mágico, que facilita nossas vidas diariamente.

Um relacionamento é a ligação entre duas classes do Active Record. Através dele podemos executar operações nos registros de forma mais fácil, como consultas e salvamento de informações. Podemos dividi-los em três tipos básicos:
- Um para um
- Um para muitos
- Muitos para muitos
Se você é novo no Rails, models são a abstração das tabelas do banco, utilizando classes do Active Record. Pense que para cada linha existente em uma tabela chamada users podemos instanciar um objeto da classe User, dentro da aplicação.
Uma das principais características do Ruby é a expressividade, permitindo que qualquer pessoa, possa ler o código e entender o que representa cada comando ou método escrito. Tal característica também é encontrada no Rails.
Vamos imaginar que estamos construindo um sistema de entregas. Isso vai nos ajudar a aplicar, de forma prática, alguns dos conceitos que vamos abordar neste artigo. Se vamos falar de entrega, é importante que nosso App tenha cadastro de usuários e endereços.
Um para um
De acordo com a documentação de nosso aplicativo, cada usuário deve possuir apenas um endereço cadastrado. Neste caso, podemos aplicar um relacionamento um para um. Vamos ver como se dá a declaração dentro das classes do ActiveRecord:
class User < ApplicationRecord
has_one :address
end
class Address < ApplicationRecord
belongs_to :user
end
Conforme podemos perceber, utilizamos métodos para indicar os relacionamentos. Em um model será utilizado o has_one e no outro será o belongs_to. Analisando o código, podemos entender que o usuário tem um endereço e que o endereço pertence a um usuário, com base nos termos em inglês aplicados para nomear os respectivos métodos.
É relevante saber que o Rails é construído sobre convenções, e assim podemos usar essa frase como mantra: O nome de uma função deve indicar o que ela faz. Caso contrário, o uso desta será desagradável.
O belongs_to ficará no model que possui a chave estrangeira. Como podemos observar na imagem abaixo, a coluna user_id faz o vínculo de informação, indicando que o endereço pertence ao usuário informado, pelo ID.

Se for seguida a convenção, o relacionamento belongs_to deve ser declarado no singular. A coluna que armazenará a referência, será o nome do relacionamento acrescido de _id. Assim foi feito no diagrama acima, indicando a coluna user_id para o relacionamento user. Por consequência, espera-se que a outra tabela possua uma chave primária, que de acordo com a convenção é a coluna id.
É importante adicionarmos um índice de unicidade no banco de dados, que impeça múltiplas duplicidade. Tal adição adição é possível via migration, conforme o exemplo abaixo.
class AddUniqueUserToAddresses < ActiveRecord::Migration[6.0]
def change
add_index :addresses, :user_id, unique: true
end
end
Um para muitos
Vamos imaginar que neste mesmo sistema um usuário possa ter mais de um pedido. Neste caso, utilizaremos um relacionamento um para muitos.
O primeiro passo é identificar em qual model terá o has_many e qual será utilizado o belongs_to. De acordo com o requisito deste sistema, um usuário pode ter vários pedidos, mas um pedido pertencerá apenas a um usuário. Sendo assim, a representação no diagrama será conforme abaixo:

Manteremos a mesma regra aplicada ao relacionamento anterior, adicionando belongs_to no mesmo model que possui a chave estrangeira, neste caso user_id. As classes do ActiveRecord ficarão assim:
class User < ApplicationRecord
has_many :orders
end
class Order < ApplicationRecord
belongs_to :user
end
Muitos para muitos
Os relacionamentos muitos para muitos podem ser declarados de duas formas no Rails. Vamos entender a diferença.
Ter e pertencer a muitos
Parece algo esquisito, lendo assim em português, mas o método has_and_belongs_to_many
significa exatamente isso. Ele cria uma associação direta, do tipo muitos para muitos, com o outro model. Para utilizá-lo basta apenas chamar o método em ambos os models.

Vamos dizer que nesse sistema seja possível adicionar múltiplos produtos a um pedido, e que um produto pode pertencer mais de um pedido. As respectivas classes seriam, como segue:
class Order < ApplicationRecord
has_and_belongs_to_many :products
end
class Product < ApplicationRecord
has_and_belongs_to_many :orders
end
Você precisará criar uma join table para que esse relacionamento funcione. Essa será uma tabela que conecta dois models diferentes. Podemos criá-la utilizando o próprio rails, através da função create_join_table
em uma migration separada.
class CreateOrdersProducts < ActiveRecord::Migration[6.0]
def change
create_join_table :orders, :products
end
end
Essa migration criará uma tabela chamada orders_products. Ela será usada para armazenar o ID do pedido e do produto que estão relacionados.
Tem muitos através de um relacionamento
Por definição, é possível criar relacionamentos que se baseiam em outros relacionamentos. Isso parece confuso, mas vamos por partes!
Vamos supor que em nosso sistema exista, além das colunas de relacionamentos, mais informações nessa tabela intermediária, como quantidade e valor unitário.

Neste caso, o ideal seria criar um terceiro model, denominado OrderProduct, e sua respectiva tabela, com todas as colunas do diagrama. Assim vamos ter mais controle durante a adição e remoção de registros, e poderemos adicionar validações, utilizar callbacks e todos os outros recursos que o ActiveRecord pode nos proporcionar. Para que isso seja possível, os relacionamentos ficarão um pouco diferente do exemplo anterior.
class Order < ApplicationRecord
has_many :order_products
has_many :products, through: :order_products
end
class Product < ApplicationRecord
has_many :order_products
has_many :orders, through: :order_products
end
class OrderProduct < ApplicationRecord
belongs_to :order
belongs_to :product
end
Esse relacionamento permitirá que você faça coisas como order.products
e obtenha uma lista de todos os produtos existentes para o pedido criado. Também permitirá que você realize o processo inverso, obtendo quais pedidos estão vinculados a um produto.
Em breve, publicarei um artigo explicando como customizar as opções dos relacionamentos, com nomes de colunas e tabelas não padronizados e até mesmo utilizando relacionamentos polimórficos.
Deixe um comentário, contando pra gente um pouco mais qual sua principal dificuldade na hora de usar o ActiveRecord.
Até a próxima!