Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Validators bleeding from one model into another.

#4964

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>

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

State: invalid
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. Neeraj Singh
    Neeraj Singh

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

    June 25th, 2010 @ 04:18 AM

  2. jdwyah
    jdwyah

    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

    !?

    June 25th, 2010 @ 04:33 AM

  3. jdwyah
    jdwyah

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

    June 25th, 2010 @ 04:39 AM

  4. Neeraj Singh
    Neeraj Singh

    what version of rails you are using?

    June 25th, 2010 @ 04:42 AM

  5. Neeraj Singh
    Neeraj Singh

    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]
    

    June 25th, 2010 @ 05:04 AM

  6. jdwyah
    jdwyah
    (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

    June 25th, 2010 @ 03:27 PM

  7. Neeraj Singh
    Neeraj Singh
    • 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?

    June 25th, 2010 @ 03:39 PM

  8. jdwyah
    jdwyah

    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.

    June 25th, 2010 @ 04:57 PM

  9. Neeraj Singh
    Neeraj Singh
    • 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.

    June 25th, 2010 @ 05:02 PM