Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Rails Active Record Callbacks: Part 3: [after_find after_initialize and conditional]

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 543
    Comment on it

    Hi friends,

    In my previous two blogs Rails Active Records Callbacks: Part 1 and Rails Active Records Callbacks: Part 2, I explained about available rails active records callbacks available. Now I will talk about some more callbacks methods available in rails:


    a) after_initialize:

    after_initialize callback is called whenever an active record object is created or initialized for the first time. Suppose you want to change some field during initialization of the object, it is best to use.

    class TestUser < ActiveRecord::Base
        after_initialize :call_after_initialize
      def call_after_initialize
        p "I am inside after initialize"
      end
    end

     

    Now in console if you run:

    # When an object is initialized
    > t = TestUser.new
    "I am inside after initialize"
    => #<TestUser id: nil, phone_number: nil, created_at: nil, updated_at: nil>
    
    # When an object is fetched from DB:
    >  t = TestUser.first
    TestUser Load (0.5ms)  SELECT  "test_users".* FROM "test_users"  ORDER BY "test_users"."id" ASC LIMIT 1
    "I am inside after initialize"
     => #<TestUser id: 1, phone_number: "+919876543210", created_at: "2016-06-08 16:19:04", updated_at: "2016-06-08 16:19:04">
    

    b) after_find:

     after_find is similar to after_initialize except that it gets called only when an object is fetched from DB and is not triggered when object is initialized. It gets called before after_initialize if both are defined for a model.

    class TestUser < ActiveRecord::Base
       after_initialize :call_after_initialize
       after_find :call_after_find
       def call_after_initialize
          p "I am inside after initialize"
        end
    
        def call_after_find
    	p "I am inside after find"
        end
    end

     

    Now in console try this:

    # When an object is initialized after_find doesn't get invoked
    
    > t = TestUser.new
    "I am inside after initialize"
    => #<TestUser id: nil, phone_number: nil, created_at: nil, updated_at: nil>
    
    # When an object is fetched from DB after_find gets called before after_initialize
    t = TestUser.first
    TestUser Load (0.5ms)  SELECT  "test_users".* FROM "test_users"  ORDER BY "test_users"."id" ASC LIMIT 1
    "I am inside after find" ## after_find gets triggered
    "I am inside after initialize" ## after_initialize gets triggered
     => #<TestUser id: 1, phone_number: "124444+91", created_at: "2016-06-08 16:19:04", updated_at: "2016-06-08 16:19:04"> 

    c) after_touch:

    As its name suggests, It gets called whenever an active record is touched. As you can see in the example given:

    class TestUser < ActiveRecord::Base
      after_touch :call_after_touch
      def call_after_touch
          p "I am inside after touch"
      end
    end
    

    Now try in console:

    t = TestUser.first
    TestUser Load (0.1ms)  SELECT  "test_users".* FROM "test_users"  ORDER BY "test_users"."id" ASC LIMIT 1
    => #<TestUser id: 1, phone_number: "124444+91", created_at: "2016-06-08 16:19:04", updated_at: "2016-06-08 16:19:04">
    
    > t.touch
    (0.2ms)  begin transaction
    SQL (0.6ms)  UPDATE "test_users" SET "updated_at" = '2016-06-11 09:47:34.498035' WHERE "test_users"."id" = ?  [["id", 1]]
    "I am inside after touch"
    (199.4ms)  commit transaction
    => true


    Conditional Callbacks:

    As a use case of adding a callback can be if in some cases we don't want a callback to be called and in same case we want it to be called, for this rails provides conditional callbacks methods that can be used to give a condition to the callback. they are :if and :unless.

    a) :if is used where we want the callback to be called when the condition given after if returns true

    b) :unless is used where we want the callback to be called when the condition given after unless returns false

    They can be used with different types. Examples are given below:

    ## with symbol
    class TestUser < ActiveRecord::Base
      before_save :update_indian_phone_number, if: :is_indian?
      before_save :update_international_phone_number, unless: :is_indian?
    end
    
    
    ## with string
    class TestUser < ActiveRecord::Base
      before_save :update_indian_phone_number, if: "is_indian?"
      before_save :update_international_phone_number, unless: "is_indian?"
    end
    
    ## with procs
    class TestUser < ActiveRecord::Base
      before_save :update_indian_phone_number, if: Proc.new { |user| user.is_indian? }
      before_save :update_international_phone_number, unless: Proc.new { |user| user.is_indian? }
    end

     

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: