Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between `before_create` and `after_create` and when to use which?

I know that before_create is called before the object gets commuted to the database and after_create gets called after.

The only time when before_create will get called and after_create while not is if the object fails to meet data base constants (unique key, etc.). Other that that I can place all the logic from after_create in before_create

Am I missing something?

like image 960
EugeneMi Avatar asked Apr 09 '14 04:04

EugeneMi


People also ask

Why do we Before_save call first and Before_create after it?

The before_save occurs slightly before the before_create . To the best of my knowledge, nothing happens between them; but before_save will also fire on Update operations, while before_create will only fire on Creates.

Which of the given callbacks is executed after the After_update?

after_save , after_create , after_update are called within the transaction block, so they will be executed before executing the SQL statement. If you want to do something when the statement execution is completed, you should use after_commit callback.

What is call back in Ruby?

Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.

What is around callback in rails?

In Rails, callbacks are hooks provided by Active Record that allow methods to run before or after a create, update, or destroy action occurs to an object. Since it can be hard to remember all of them and what they do, here is a quick reference for all current Rails 5 Active Record callbacks.


2 Answers

In order to understand these two callbacks, firstly you need to know when these two are invoked. Below is the ActiveRecord callback ordering:

(-) save

(-) valid

(1) before_validation

(-) validate

(2) after_validation

(3) before_save

(4) before_create

(-) create

(5) after_create

(6) after_save

(7) after_commit

you can see that before_create is called after after_validation, to put it in simple context, this callback is called after your ActiveRecord has met validation. This before_create is normally used to set some extra attributes after validation.

now move on to after_create, you can see this is created after the record is stored persistently onto DB. People normally use this to do things like sending notification, logging.

And for the question, when should you use it? The answer is 'you should not use it at all'. ActiveRecord callbacks are anti-pattern and seasoned Rails developer consider it code-smell, you can achieve all of that by using Service object to wrap around. Here is one simple example:

class Car < ActiveRecord::Base
  before_create :set_mileage_to_zero
  after_create  :send_quality_report_to_qa_team
end

can be rewritten in

# app/services/car_creation.rb

class CarCreation

  attr_reader :car

  def initialize(params = {})
    @car = Car.new(params)
    @car.mileage = 0
  end

  def create_car
    if car.save
      send_report_to_qa_team
    end 
  end

  private

  def send_report_to_qa_team
  end
end

If you have simple app, then callback is okay, but as your app grows, you will be scratching your head not sure what has set this or that attribute and testing will be very hard.

On second thought, I still think you should extensively use callback and experience the pain refactoring it then you'll learn to avoid it ;) goodluck

like image 173
Trung Lê Avatar answered Oct 09 '22 22:10

Trung Lê


before_create:

will be called before saving new object in db. When this method will return false it will prevent the creation by rolling back.

So when you need to do something like check something before saving which is not appropriate in validations you can use them in before_create.

For example: before creation of new Worker ask Master for permission.

before_create :notify_master

def notify_master
  # notify_master via ipc and 
  # if response is true then return true and create this successfully
  # else return false and rollback
end

Another use is as Trung Lê suggested you want to format some attribute before saving like capitalizing name etc.

after_create:

Called after saving object in database for first time. Just when you don't want to interrupt creation and just take a note of creation or trigger something after creation this is useful.

for example: After creating new user with role mod we want to notify other mods

after_create :notify_mod, :is_mod?

def notify_mod
  # send notification to all other mods
end

EDIT: for below comment

Q: What's the advantage of putting notify_mod in after_create instead of before_create?

A: Sometimes while saving the object in database it can rollback due to database side validations or due to other issues.

Now if you have written notify_mod in before create then it will be processed even if the creation is not done. No doubt it will rollback but it generates overhead. so it's time consuming

If you have placed it in after_create then notify_mod will only execute if the record is created successfully. Thus decreasing the overhead if the rollback takes places.

Another reason is that it's logical that notification must be sent after user is created not before.

like image 31
Hardik Avatar answered Oct 09 '22 20:10

Hardik