Search code examples
ruby-on-railsdevise

Devise: => #<NoMethodError: undefined method `downcase!' for 1:Fixnum>


This may or may not be a devise error, but I think it is.

In testing I tried assigning an integer as the email address. I am getting this error from the 'bowels' of active record save:

=> #<NoMethodError: undefined method `downcase!' for 1:Fixnum>

This is despite the fact that I have this validation on my User < ActiveRecord::Base.

validates :email, format: { with: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i, message: "Invalid email"}

I am guessing that somehow some devise validation or other hook is being called on the email address and blowing up. What can I try next?


Solution

  • Have a look at the Devise sourcecode:

    The authenticable module adds before_validation :downcase_keys, which does the following:

    def downcase_keys
        self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase!) }
    end
    

    (see lib/devise/models/authenticatable.rb for reference)

    It is used to downcase all case insensitive keys before applying any logic to the models. By default configuration provided by Devise, case_insensitive_keys contains the email field you are setting with a Fixnum.

    # Keys that should be case-insensitive.
    mattr_accessor :case_insensitive_keys
    @@case_insensitive_keys = [ :email ]
    

    (see lib/devise.rb for reference)

    This way, the validation is executed even before your own validation is checked. Perhaps an additional verification for the variable's type could be added to Devise, but by default you'll only assign a String provided by the login / etc. form to that field.

    I hope i could clarify this a bit.