Reputation: 17467
(update: typo in image):
after_initialize :set_default_role, :if => :new_record?
So given the above code, I'm curious is there a name for the :if => :new_record?
syntax?
Why is the if
statement written as a hash?
Is there a difference if its written as:
after_initialize :set_default_role if self.new_record?
Upvotes: 0
Views: 864
Reputation: 7268
First of all, the after_initialize
syntax is incorrect in your code.
Instead of:
after_initialize: set_default_role
,
you should call
after_initialize :set_default_role
.
That said, after_initialize
here is a normal method call from the class body (yes, it's possible in Ruby). It's called once, when the class is loaded. This method, when invoked, sets a callback (first parameter), to be triggered, in this case, when your Active Record object is instantiated).
In this case :if
is a key option passed to the after_initialize
method. It's the same as if you were calling the method like this:
after_initialize(:set_default_role, { if: :new_record? })
Second parameter: Hash Object with some options.
Just a note: :if => :new_record?
(hashrocket notation) is the same of if: :new_record?
(new syntax, JSON-like).
So, if
here is just the key name of the options Hash Object passed as the second argument of the method invocation (not the conditional if
keyword).
By the way, you can read more about Conditional Callbacks here.
after_initialize :set_default_role if self.new_record?
won't work?
That's because this method is called in the class body, with the Class context (self = User
, not self = @user
) - once when loaded -, and new_record?
is an instance method. The interpreter would throw a undefined method 'new_record?'
error.
When you correctly set if:
key to :new_record?
, it works like a pointer. You're saying: ok, I'm defining now, in my Class context that, when the time comes (this Active Record object is instantiated), you will look for a method called set_default_role
in my class instance, but only if the instance method new_record?
returns true
.
Upvotes: 1