0

I'm using Rails 4.0.0. I have the following setup:

class Foo < ApplicationController

  before_validation :foo, on: :create

  ...

  private

    def bar
      puts 'bar is called'
    end
end

This works - in the console, when I create a foo, I see the message 'bar is called'. If I call valid? on foo the message is not called (correct behavior).

Now I want to add this callback also upon update. I've tried two things:

before_validation :foo, on: [:create, :update]

and

before_validation :foo, on: :create
before_validation :foo, on: :update

In both cases I see the following problem. In the console, if I instantiate a foo like so: foo = Foo.last and then call foo.valid?, I see the bar triggered, although I do not update the foo. I expect it to be called only after foo.update(...). Am I doing something wrong or is this an expected behavior?

Alexander Popov
  • 23,073
  • 19
  • 91
  • 130

1 Answers1

1

Since you are assigning an old record into foo by foo = Foo.last, it will take :update as context while running the validations against foo. Where as, on: :create validations are only checked for new record.

If you study the valid? method implementation, it will be clear:

def valid?(context = nil)
  context ||= (new_record? ? :create : :update)
  output = super(context)
  errors.empty? && output
end

Hope this helps.

Sharvy Ahmed
  • 7,247
  • 1
  • 33
  • 46