after_commit is a type of active record callback.
after_commit是活动记录回调的一种。
什么是活动记录回调? (What are Active Record Callback?)
Active Record Callbacks helps us to execute code at certain stages of object life-cycle. Read more about it here.
Active Record回调有助于我们在对象生命周期的某些阶段执行代码。 在此处了解更多信息。
In order to understand where we should use after_commit callback, let’s take a scenario of an organisation where we have to add a member in it. Whenever that is done, we need to notify organisation’s admin through email about the added member.
为了了解我们应该在哪里使用after_commit回调,让我们以一个组织的场景为例,我们必须在其中添加成员。 无论何时,我们都需要通过电子邮件通知组织的管理员有关所添加成员的信息。
To achieve this use-case, many of us would go for active-record’s after_save callback.
为了实现此用例,我们中的许多人都将使用active-record的after_save回调 。
And why should we not? One would wonder.
为什么不呢? 有人会怀疑。

Using after_save would fulfils our requirement in this scenario. So there shouldn’t be a problem.
在这种情况下,使用after_save将满足我们的要求。 因此应该没有问题。
# 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
But here, my friend, even though code looks perfectly fine, there may be a glitch in it.
但是在这里,我的朋友,即使代码看起来很好,但其中也可能存在故障。
The after_save callback will be executed after the user record is saved to database but the transaction is still not complete. We know about the Atomicity principle (ACID Properties), that a database runs everything in a transaction. If somehow due to any other operation the transaction fails to complete, then the database will revert the addition of member.
将用户记录保存到数据库中之后,将执行after_save回调,但是事务仍未完成。 我们知道原子性原理(ACID属性),即数据库运行事务中的所有内容。 如果某种原因由于任何其他操作导致事务无法完成,则数据库将还原成员的添加。
In that case, since the email job has already started running in the background, It will raise a NotFound exception when it runs self.id.
在这种情况下,由于电子邮件作业已经开始在后台运行,它将引发NotFound异常 当它运行时 self.id。
So, how to overcome this?
那么,如何克服呢?

In order to solve this, we need to use after_commit callback in place of after_save.
为了解决这个问题,我们需要使用after_commit回调代替after_save 。
after_commit callback will ensure that the send_email_notifications method is executed only when the commit transaction completes in the database.
after_commit回调将确保仅在数据库中的提交事务完成时才执行send_email_notifications方法。
# app/models/user.rb
class User < ApplicationRecord
after_commit :send_email_notifications, on: :create
def send_email_notifications
# This will send email notifications in the background
SendEmailNotifications.perform_later(self.id)
end
end
So, what did we learn here ?We should always think before using callbacks, which one of them will satisfy our requirements and then use it.
所以,我们在这里学到了什么?在使用回调之前,我们应该始终思考一下,其中之一将满足我们的要求,然后再使用它。
Hope you liked this information. For more such information stay tuned.Happy Coding ….. :)
希望您喜欢此信息。 有关更多此类信息,请继续关注。快乐编码….. :)
翻译自: https://medium.com/stackavenue/when-to-use-after-commit-in-rails-f5e53a22bb9