This project is archived and is in readonly mode.

#2183 ✓invalid
Jacob Burkhart

Avoid infinite recursive validation when validate => true

Reported by Jacob Burkhart | March 9th, 2009 @ 06:14 PM | in 2.x

An outgrowth of #2144. Since the solution to my problem was apparently "validate => true". This happens to be a problem for my situation.

I happen to be in a situation like this:


  def test_do_the_right_thing_on_validate
    Pirate.class_eval do
      belongs_to :parrot, :validate => true
    end
    Parrot.class_eval do
      has_and_belongs_to_many :pirates, :validate => true
    end
    
    pirate = Pirate.new(:catchphrase => "Figure out how to validate me please")
    pirate.parrot = Parrot.new
    pirate.parrot.pirates << pirate

    #because the parrot doesn't have a name, this save should fail invalid
    assert_raises(ActiveRecord::RecordInvalid){
      pirate.save!      
    }
  end

And, as you might have guessed, if you run this test....


  1) Failure:
test_do_the_right_thing_on_validate(TestStuff)
    [./test/cases/autosave_association_test.rb:883:in `test_do_the_right_thing_on_validate'
     ./test/cases/../../../activesupport/lib/active_support/testing/setup_and_teardown.rb:57:in `__send__'
     ./test/cases/../../../activesupport/lib/active_support/testing/setup_and_teardown.rb:57:in `run']:
<ActiveRecord::RecordInvalid> exception expected but was
Class: <SystemStackError>
Message: <"stack level too deep">
---Backtrace---
./test/cases/../../lib/active_record/callbacks.rb:312:in `valid?'
./test/cases/../../lib/active_record/associations/association_proxy.rb:221:in `send'
./test/cases/../../lib/active_record/associations/association_proxy.rb:221:in `method_missing'
./test/cases/../../lib/active_record/autosave_association.rb:249:in `association_valid?'
./test/cases/../../lib/active_record/autosave_association.rb:229:in `validate_single_association'
./test/cases/../../lib/active_record/autosave_association.rb:183:in `validate_associated_records_for_parrot'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:180:in `evaluate_method'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:180:in `evaluate_method'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:180:in `instance_eval'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:180:in `evaluate_method'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:166:in `call'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:90:in `run'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:90:in `each'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:90:in `send'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:90:in `run'
./test/cases/../../../activesupport/lib/active_support/callbacks.rb:276:in `run_callbacks'
./test/cases/../../lib/active_record/validations.rb:1029:in `valid_without_callbacks?'
./test/cases/../../lib/active_record/callbacks.rb:315:in `valid?'
...
./test/cases/../../lib/active_record/callbacks.rb:315:in `valid?'
./test/cases/../../lib/active_record/validations.rb:1018:in `save_without_dirty!'
./test/cases/../../lib/active_record/dirty.rb:87:in `save_without_transactions!'
./test/cases/../../lib/active_record/transactions.rb:200:in `save!'
./test/cases/../../lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
./test/cases/../../lib/active_record/transactions.rb:182:in `transaction'
./test/cases/../../lib/active_record/transactions.rb:200:in `save!'
./test/cases/../../lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
./test/cases/../../lib/active_record/transactions.rb:200:in `save!'
./test/cases/autosave_association_test.rb:884:in `test_do_the_right_thing_on_validate'
./test/cases/autosave_association_test.rb:883:in `test_do_the_right_thing_on_validate'
./test/cases/../../../activesupport/lib/active_support/testing/setup_and_teardown.rb:57:in `__send__'
./test/cases/../../../activesupport/lib/active_support/testing/setup_and_teardown.rb:57:in `run'
---------------

Comments and changes to this ticket

  • Jacob Burkhart

    Jacob Burkhart March 9th, 2009 @ 06:15 PM

    • Title changed from “Avoid recursive validation when validate => true” to “Avoid infinite recursive validation when validate => true”
  • Eloy Duran

    Eloy Duran March 9th, 2009 @ 08:10 PM

    • Assigned user set to “Eloy Duran”
  • Pratik

    Pratik March 10th, 2009 @ 11:35 AM

    • Assigned user changed from “Eloy Duran” to “Pratik”
    • State changed from “new” to “invalid”

    I'd usually put :validate => false in one of the models and raise exception from an after_save callback if something didn't validate well and rely on transaction thingy to roll it all back.

    Thanks.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages