Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Skip instance in conditional callback block (lambda or Proc)

I noticed that almost all people use Proc.new instead of lambda (I guess because of how it cares/or not about arity) and also it's common to pass the current instance as an argument. However I checked and it works also without |instance| passed as an arg. See the example below

class SomeModel < ActiveRecord::Base
  has_many :associated_objects

  before_save :do_something, if: -> { associated_objects.empty? }
end

According to official guide and most posts found on the Internet it seems that I should write

before_save :do_something, if: Proc.new { |instance| instance.associated_objects.empty? }

Is there something wrong with my example using -> and no argument? It's similar to skipping the self as the receiver in self.some_method inside model's code and using the implicit receiver.

like image 580
januszm Avatar asked Oct 12 '25 08:10

januszm


1 Answers

You've got it right, the scope of what's evaluated in the Proc or lambda is automatically set to the current instance of the object you're about to save.

From the rails docs you can see if you wanted to define your own callbacks you have the option to use a Proc or a lambda with the object in scope.

If a proc, lambda, or block is given, its body is evaluated in the context of the current object. It can also optionally accept the current object as an argument.

I find it interesting that the Rails Guides recommend passing in the current instance into the Proc when (as you outlined) it is very common place to leave that info out elsewhere when self is implied.

like image 191
Anthony Avatar answered Oct 15 '25 13:10

Anthony