In pure Ruby irb, one cannot type {if: 1}
. The statement will not terminate, because irb thinks if
is not a symbol but instead the beginning of an
The code in your example is part of the Rails DSL. What you are actually setting there is a hash which just happens to look a bit like code.
Internally, Rails will evaluate this hash specifying conditions to the before_save
call.
In a very simplified version, Rails basically does this when saving:
class ActiveRecord::Base
@before_save_rules = []
def self.before_save(method, options={})
@before_save_rules << [method, options]
end
def self.before_save_rules
@before_save_rules
end
def save
# Evaluate the defined rules and decide if we should perform the
# before_save action or not
self.class.before_safe_rules.each do |method, options|
do_perform = true
if options.key?(:if)
do_perform = false unless send(options[:if])
end
if options.key?(:unless)
do_perform = false if send(options[:unless])
end
send(method) if do_perform
end
# now perform the actual save to the database
# ...
end
end
Again, this is very simplified and just in the spirit of actual code, but this is basically how it works.