Quando e por que usar after_commit no Rails?
O uso correto de callbacks no rails.
O que são Active Record Callbacks?
Os callbacks do Active Record nos ajudam a executar o código em certos estágios do ciclo de vida do objeto. Leia mais sobre isso aqui .
Para entender onde devemos usar o callback after_commit
, vamos pegar o cenário de uma aplicação onde temos que adicionar um usuário a ela. Sempre que isso for feito, precisamos notificar o administrador da aplicação por e-mail sobre o membro adicionado.
Para atingir esse caso de uso, muitos de nós optamos pelo callback after_save do active-record .
E por que não deveríamos? Você poderia se perguntar.
O uso de after_save
atenderia aos nossos requisitos neste cenário. Portanto, não deve haver problema.
# app/models/user.rb
class User < ApplicationRecord
after_save :send_email_notifications
def send_email_notifications
# This will send email notifications in the background
SendEmailNotifications.perform_later(self.id)
end
end
Mas aqui, meu amigo, embora o código pareça perfeitamente implementado, pode haver uma falha nele.
O retorno de chamada after_save
será executado após o registro do usuário ser salvo no banco de dados, mas a transaction ainda não foi concluída.
Sabemos sobre o princípio de Atomicidade (ACID), que um banco de dados executa tudo em uma transaction. Se de alguma forma, devido a qualquer outra operação, a transaction não for concluída, o banco de dados reverterá a adição do usuário.
Nesse caso, a chamada do serviço de e-mail já começou a ser executado em segundo plano, ele gerará uma exceção NotFound
ao executar self.id
.
Então, como superar isso?
Para resolver isso, precisamos usar callback after_commit
no lugar de after_save
.
O callback after_commit garantirá que o método send_email_notifications seja executado apenas quando a transação de confirmação for concluída no banco de dados.
Conclusão
Aprendemos hoje que antes de usar callbacks, devemos sempre pensar em qual deles irá satisfazer nossos requisitos e então usá-lo.
Espero que você tenha gostado desta informação.