ActiveRecord Callbacks you need to know
Tags: rails, ruby, webdev, beginners
Published: 2020-07-24 11:12:37

---
title: ActiveRecord Callbacks you need to know
published: true
description: 
tags: #rails #ruby #webdev #beginners
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/omi75xgy8acod9d906x7.png
---
Hi everyone.

This week, we will be talking about some ActiveRecord callbacks you need to know and when to use them. In a Rails application, objects may be created, updated, and destroyed and ActiveRecord provides hooks into this object life cycle so that you can control your application and its data. This callbacks are methods or functions you want to trigger before or after the state of an object changes. You will see its usage like:

```ruby
class Article < ApplicationRecord
  after_destroy :log_destroy_action
 
  def log_destroy_action
    puts 'Article destroyed'
  end
end
```

The above callback is called after an article has been destroyed. You could rewrite it as what we have below if what you want to do is minimal but it's more advisable to use the format above for a much cleaner code.

```ruby
class Article < ApplicationRecord
  after_destroy do
    puts 'Article destroyed'
  end
end
```

Below is a list of the callbacks we will be going through;

* before_validation
* after_validation
* before_save
* around_save
* before_create
* around_create
* after_create
* after_save
* after_commit/after_rollback
* before_update
* around_update
* after_update
* before_destroy
* around_destroy
* after_destroy

I am sure some of the names are self explanatory so I will focus on when to use and examples of how they can be used

##### before_validation
Actions that trigger it: `:create`, `:update`

This callback is used before the model validation takes place. For example, for our Article model, if we want to set the title a value in the case that it is empty, we can do in a `before_validation`.

```ruby
class Article < ApplicationRecord
  validates :title, presence: true

  before_validation :ensure_title_has_a_value
 
  private

  def ensure_login_has_a_value
    if title.nil?
      self.title = "Title #{Title.all.count + 1}"
    end
  end
end
```

##### after_validation
Actions that trigger it: `:create`, `:update`

This callback is used after the model validation takes place. For our Article model, if we want to capitalize the title of the article, we can do in the `after_validation`.

```ruby
class Article < ApplicationRecord
  validates :title, presence: true

  after_validation :capitalize_title
 
  private

  def capitalize_title
    self.title = title.capitalize
  end
end
```

##### before_save
Actions that trigger it: `:create`, `:update`

This callback is called before the object is saved to the database. For our Article model, if we want to capitalize the title of the article, we can do in the `after_validation`.

```ruby
class Article < ApplicationRecord
  validates :title, presence: true

  before_save :log_message
 
  private

  def log_message
    puts "You are about to save an article"
  end
end
```

##### around_save
Actions that trigger it: `:create`, `:update`

This callback is called around the saving the object and inside the before_save and after_save actions. Please note that you need to put a yield in the around_save method so that the action(`save`) can be performed. For example, if we have an article with the callbacks below;

```ruby
class Article < ApplicationRecord
  validates :title, presence: true

  before_save :call_before_save
  after_save :call_after_save
  around_save :call_around_save
 
  private

  def call_before_save
    puts 'before article is saved'
  end

  def call_after_save
    puts 'after article is saved'
  end

  def call_around_save
    puts 'in around article save'
    yield # Article saved
    puts 'out around article save'
  end
end
```

When we initialize and save a new Article. We should have the following output;

```
article = Article.new(title: 'My title')
article.save
  before article is saved
  in around article save
  out around article save
  after article is saved
```

From the above output, you see that the `before_save` block is called first, next the `around_save` block. The method first logs the first line, then yields to the save action so the article can be saved to the database. After the save action is complete, control is then returned back to the `call_around_save` method which logs the last line and then passes control to the `after_save` callback.

##### before_create
Actions that trigger it: `:create`

This callback is the same as the `before_save`. The only difference is that it is triggered only by the `create` action. 

Note: In a creation operation, the `before_save` is usually called before the `before_create` callback.

##### around_create
Actions that trigger it: `:create`

This callback is the same as the `around_save`. The difference between them is that it is triggered only by the `create` action. 

##### after_create
Actions that trigger it: `:create`

This callback is the same as the `after_save`. The only difference is that it is triggered only by the `create` action. 

##### after_save
Actions that trigger it: `:create`, `:update`

This callback is the executed after the object has been saved to the database. It is mostly used when you want to log database changes or track who made changes and in some case, make api call to a third party service 

```ruby
class Article < ApplicationRecord
  validates :title, presence: true

  after_save :tell_salesforce_i_created_a_new_article
 
  private

  def tell_salesforce_i_created_a_new_article
    puts "Send a message to salesforce via HTTPS with my details"
  end
end
```

##### before_update
Actions that trigger it: `:update`

This callback is the same as the `before_save`. The difference is that it is triggered only by the `update` action. 

##### around_update
Actions that trigger it: `:update`

This callback is the same as the `around_save`. The difference between them is that it is triggered only by the `update` action. 

##### after_update
Actions that trigger it: `:update`

This callback is the same as the `after_save`. The only difference is that it is triggered only by the `update` action. 

##### before_destroy
Actions that trigger it: `:destroy`

This callback is triggered before an object is deleted from the database. You can use this to check for relationships that might be affected by its unavailability and either update those relationships or stop this action. In the case of our articles, if we have a table that saves medias or files associated with it, we can use the `before_destroy` callback to check that this article doesn't have a relationship saved in that table. If it exists, we can stop the action from going forward.

##### around_destroy
Actions that trigger it: `:destroy`

This callback works like the `around_save` but only for a `destroy` action.

##### after_destroy
Actions that trigger it: `:destroy`

This callback is triggered after an object has been deleted. Mostly utilized for cleanups. It can be used to update records, make an API call to a 3rd party service to notify it that the object has been deleted or trigger a background job.

##### after_commit/after_rollback
Actions that trigger it: `:create`, `:update`, `:destroy`

This callback is called after an object has been created, updated or destroyed. It can replace the `after_save`, `after_update`, `after_update` or `after_destroy` callbacks. You use this method when you want to run the same method when any of these 3 actions are executed.

#### Extras

##### after_initialize
The `after_initialize` callback is called whenever an object is instantiated, either by directly using `new` keyword or when a record is loaded from the database.

##### after_find
The `after_find` callback is called whenever Active Record finds and loads a record from the database.

### Resources
* [ActiveRecord Callback](https://guides.rubyonrails.org/active_record_callbacks.html#available-callbacks)
* [Around_save question on Stackoverflow - Answer 2](https://stackoverflow.com/questions/4998553/rails-around-callbacks)
* [Rails Callback Cheatsheet](https://medium.com/@juliannaroen/rails-callbacks-cheat-sheet-824295a1a14d#:~:text=around_save,in%20the%20method%20will%20execute.)
* [Difference between before_save and before_create - Stackoverflow](https://stackoverflow.com/questions/6249475/ruby-on-rails-callback-what-is-difference-between-before-save-and-before-crea)