This project is archived and is in readonly mode.

#4964 ✓invalid
jdwyah

Validators bleeding from one model into another.

Reported by jdwyah | June 25th, 2010 @ 03:14 AM

My User model has 11 validations.

However:
1) User.validators.count = 42
2) User.validators.map{|v| v.instance_variable_get('@klass')}
returns lots of classes that aren't the User class.

3) I have another model: MembershipRequest. Formtastic does some reflection on this model. This creates an error because it is finding a validation on the User class but trying to run it on an instance of MembershipRequest.

user.rb
validates_numericality_of :zip_code, :phone_number, :if => Proc.new { |user| user.signup_step > 0 }

Error from formtastic:
undefined method signup_step' for #<MembershipRequest:0x4bcd050>

Comments and changes to this ticket

  • Neeraj Singh

    Neeraj Singh June 25th, 2010 @ 04:18 AM

    can you list all your 11 validations. I randomly added 5 validations and I am getting the count as 5.

  • jdwyah

    jdwyah June 25th, 2010 @ 04:33 AM

    validates_presence_of :first_name, :last_name, :address1, :city, :state, :zip_code, :phone_number,

                                :if => Proc.new { |user| user.signup_step > 0 }
    

    validates_numericality_of :zip_code, :phone_number,

                                :if => Proc.new { |user| user.signup_step > 0 }
    

    How's this for weird:
    (rdb:3) p Piece.validators.count 40
    (rdb:3) p User.validators.count 40
    (rdb:3) p MembershipRequest.validators.count 40
    (rdb:3) p Artist.validators.count 41
    (rdb:3) p MembershipRequest.validators.count 41

    !?

  • jdwyah

    jdwyah June 25th, 2010 @ 04:39 AM

    Neeraj, did you try two models, five validations each?

  • Neeraj Singh

    Neeraj Singh June 25th, 2010 @ 04:42 AM

    what version of rails you are using?

  • Neeraj Singh

    Neeraj Singh June 25th, 2010 @ 05:04 AM

    works fine for me

    ruby-1.8.7-p249 > User.validators.count
     => 2 
    ruby-1.8.7-p249 > Comment.validators.count
     => 2 
     ActiveRecord::Schema.define(:version => 20100625031507) do
    
       create_table "comments", :force => true do |t|
         t.string "first_name"
         t.string "last_name"
         t.string "address1"
         t.string "city"
         t.string "state"
         t.string "zip_code"
         t.string "phone_number"
       end
    
       create_table "users", :force => true do |t|
         t.string "first_name"
         t.string "last_name"
         t.string "address1"
         t.string "city"
         t.string "state"
         t.string "zip_code"
         t.string "phone_number"
       end
    
     end
     class Comment < ActiveRecord::Base
       validates_presence_of :first_name, :last_name, :address1, :city, :state, :zip_code, :phone_number,:if => Proc.new { |user| user.signup_step > 0 }
    
       validates_numericality_of :zip_code, :phone_number,
       :if => Proc.new { |user| user.signup_step > 0 }
    
     end
     class User < ActiveRecord::Base
       validates_presence_of :first_name, :last_name, :address1, :city, :state, :zip_code, :phone_number,:if => Proc.new { |user| user.signup_step > 0 }
    
       validates_numericality_of :zip_code, :phone_number,
       :if => Proc.new { |user| user.signup_step > 0 }
    
     end
     #rails -v : Rails 3.0.0.beta4
     #ruby -v : ruby 1.8.7 (2010-01-10 patchlevel 249) [i686-darwin10.3.0]
    
  • jdwyah

    jdwyah June 25th, 2010 @ 03:27 PM

    (rdb:1) p User._validators == MembershipRequest._validators
    true
    

    Seems like that's the root of the issue. I see that this uses the new class_attribute :_validators

    It makes sense that if this class_attribute subclassing were to malfunction I would see the errors I'm getting. Obviously it works for you, but I can't pinpoint what else I may have done to break class_attribute.

    I get the same results for 3.0.0.beta4 & 3.0.0.beta3

  • Neeraj Singh

    Neeraj Singh June 25th, 2010 @ 03:39 PM

    • Tag changed from validations to rails3, validations

    If you look at the very bottom of validators.rb in AM you will see this

         # Copy validators on inheritance.
          def inherited(base)
            dup = _validators.dup
            base._validators = dup.each { |k, v| dup[k] = v.dup }
            super
          end
    

    It means each model is getting its own copy of _validators. This is what I am getting

    ruby-1.8.7-p249 > p User._validators == Comment._validators
    false
     => nil 
    ruby-1.8.7-p249 > p User._validators.equal? Comment._validators
    false
     => nil
    

    I am running rails edge. YOu mentioned beta4. Can you try with edge?

  • jdwyah

    jdwyah June 25th, 2010 @ 04:57 PM

    Looks like that did it! Rest of my gems aren't happy with edge so can't test the actual failure, but at least the objects aren't sharing validators.

    Yikes. That was a scary one.

  • Neeraj Singh

    Neeraj Singh June 25th, 2010 @ 05:02 PM

    • State changed from “new” to “invalid”

    Now I remember. This issue was raised earlier and I patched it http://github.com/rails/rails/commit/e11bb95d56ed77b10d54d9dfe5a3cc... . Later Mr. Valim changed it further.

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>

People watching this ticket

Pages