timpone
timpone

Reputation: 19969

not sure why a Proc would be used here - not getting something simple

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

Answers (2)

Zach Kemp
Zach Kemp

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

Daniel Evans
Daniel Evans

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

Related Questions