Reputation: 19969
I understand the concept of a proc but sometime I see code like this (take from rails guide for validation http://guides.rubyonrails.org/active_record_validations_callbacks.html#using-if-and-unless-with-a-proc):
class Order < ActiveRecord::Base
before_save :normalize_card_number,
:if => Proc.new { |order| order.paid_with_card? }
end
it seems this could be more simply written as:
class Order < ActiveRecord::Base
before_save :normalize_card_number, :if => :paid_with_card?
end
What am I not getting about the advantage of using a Proc here?
thx in advance
Upvotes: 4
Views: 74
Reputation: 11904
They are equivalent if the receiver of the method is the object being validated. This isn't exactly how the ActiveModel validators work, but the concept is similar:
Calling to_proc
on a symbol :sym
gives you the functional equivalent of ->(x){ x.sym } - the symbol is sent as a message to the argument of the proc. Calling to_proc
on a proc simply returns itself, so you can pass either a symbol or proc into a method and guarantee a proc:
def return_a_proc(symbol_or_proc)
symbol_or_proc.to_proc
end
In cases where the model instance is not the receiver, e.g. the validation method takes the model as an argument, or as in Daniel Evans' example, you need to explicitly construct the proc to specify what should be done with the proc's argument.
Upvotes: 1
Reputation: 6818
In simple cases they are equivalent, but procs allow far more versatility without requiring a method to be defined simply for a validation if check.
Imagine this:
before_save :nuke, :if => Proc.new { |model| !model.nuked? && model.nukable? && model.region.nukable? }
You can always write that check in an instance method and reference it with a symbol, but for cases where the specific logic is only in the :if, it is valid to keep it in a proc.
Upvotes: 5