Callbacks are calling...
Published: 2021-03-16 15:30:24



 Writing my second blog for Flatiron has taken me down some worm holes. Which hasn't been a bad thing! While learning Ruby on Rails we came across Validations, and how/when to use them. Validations are used to ensure that only valid data is saved into your database. Seems like a secure way to handle information. A Callback is called before or after the Validation is called. These actions happen fast and are considered magic.


-Callbacks are methods that get called at certain moments of an object’s life cycle. With them is possible to write code that will run whenever an ActiveRecord object is created, saved, updated, deleted, validated or loaded from the database - Ruby on Rails Guide

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2xutite9iapjd45ggoxf.jpg)

In rails c, 
```Ruby
run    ActiveRecord::Callbacks::CALLBACKS
```

 ```Ruby
=> [:after_initialize, :after_find, :after_touch,
 :before_validation, :after_validation, :before_save,
 :around_save, :after_save, :before_create, :around_create,
 :after_create, :before_update, :around_update, :after_update,
 :before_destroy, :around_destroy, :after_destroy, 
:after_commit, :after_rollback]
``` 

this is a list of available callbacks. 


In order to use callbacks, you need to register them. Which means you need to add them to your Model using the correct method. You can do this four different ways:
  * Method references (symbol)- recommended
  * Callback objects -recommended
  * Inline methods (using a proc)-when appropriate
  * Inline evals methods (using a string)-deprecated


Here are some examples on how to use them. These code examples are from the ActiveRecords guide page
http://guides.rubyonrails.org/active_record_callbacks.html

```Ruby 
class User < ApplicationRecord
  validates :login, :email, presence: true

  before_validation :ensure_login_has_a_value

  private
    def ensure_login_has_a_value
      if login.nil?
        self.login = email unless email.blank?
      end
    end
end
```



  This callback before_validation is making sure that the user has a valid login before it will run the validates method.  By calling the ensure_login_has_a_value method wrote in the private section in the User class.  Everything happens here in the model. 


You can pass blocks ( useful for short one-liner logic )

```Ruby
class User < ApplicationRecord
  validates :login, :email, presence: true

  before_create do
    self.name = login.capitalize if name.blank?
  end
end
```


Callbacks can also be registered to only fire on certain life cycle events:

```Ruby
       class User < ApplicationRecord
          before_validation :normalize_name, on: :create

        # :on takes an array as well
          after_validation :set_location, on: [ :create, 
          :update ]

     private
         def normalize_name
           self.name = name.downcase.titleize
          end
        def set_location
           self.location = LocationService.query(self)
          end
       end 
```


 Here before_validation is calling the normalize_name method on: :create. Which will make sure the User name is in downcase and titlized. The after_validation is calling the set_location method on: [ :create, :update ] 


Relational Callbacks: 

```Ruby
      class User < ApplicationRecord
        has_many :articles, dependent: :destroy
      end

      class Article < ApplicationRecord
        after_destroy :log_destroy_action

      def log_destroy_action
        puts 'Article destroyed'
       end
     end
irb>
user = User.first
=> #<User id: 1>
irb>
user.articles.create!
=> #<Article id: 1, user_id: 1>
irb>
user.destroy
Article destroyed
=> #<User id: 1>
```

 Here the user has many accounts and when they delete their account all their articles should be deleted as well by using dependent: :destroy.

 Another example of registering callbacks with callback macros is that they are inheritable

```Ruby
     class Sweet < ApplicationRecord
       before_save :do_something_with_sweet
     end
```

```Ruby
     class Vendor < ApplicationRecord
       before_save :do_something_with_vendor
     end
```

 Here when the save method is call on Vendor instance, both :do_something_with_sweet and :do_something_with_vendor are triggered.


```Ruby
    class Comment < ApplicationRecord
     after_create :send_email_to_author, if: 
      :author_wants_emails?,
     unless: Proc.new { |comment| 
       comment.article.ignore_comments? }
    end
```

 Here the after_create will send_email_to_author if author_wants_emails.
unless (Proc is looping thorough all the comments) and the people who had comments wouldn't get an email.


 It’s possible to skip callbacks with these methods: http://guides.rubyonrails.org/active_record_callbacks.html
    
* decrement!
* decrement_counter
* delete
* delete_all
* delete_by
* increment!
* increment_counter
* insert
* insert!
* insert_all
* insert_all!
* touch_all
* update_column
* update_columns
* update_all
* update_counters
* upsert
* upsert_all


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/oqgxdztqu0c7f3sq24b5.jpg)

 Conclusion, There are so many different fun ways for Callbacks to be used. They are magical and should be used sparingly. Using too many could become a problem and hard to navigate. I hope this was helpful.