开发者

undefined method 'hashed_password' Agile Web development with rails

I'm following Iteration 13 of Agile Web development, for User login.

I create a migration to add 2 columns to my User model : hashed_password and salt.

  • Creation of Users works
  • login fails, due to this error undefined method 'hashed_password' in method 'authenticate'

The problem is that :

  • In rails console, I can fetch User.first.hashed_password, what seems OK :-)
  • I outputted the User that I fecth, and it is NOT nil
  • I tried to output user.hashed_password as I did in the rails console, but that throws always the same error :

NoMethodError (undefined method hashed_password' for #<ActiveRecord::Relation:0x00000003e6c3c0>): app/models/user.rb:21:inauthenticate' app/controllers/sessions_controller.rb:6:in `create'

This is my User model :

require 'digest/sha2'

class User < ActiveRecord::Base
has_and_belongs_to_many :products
has_many :created_products, :class_name => "Product", :foreign_key => :product_id

default_scope :order => "username ASC"


# Attributs pour le login (Livre)
validates :username, :presence => true, :uniquenes开发者_运维问答s => true
validates :password, :confirmation => true
attr_accessor :password_confirmation
attr_reader :password
validate :password_must_be_present

def User.authenticate(name, password)
    logger.debug "---------- Beginning of Authenticate"
    if user = User.where(:username => name)

      logger.debug "utilisateur = #{user.inspect}"   # THIS IS OK AND NOT NIL
      logger.debug "utilisateur hashed PW = #{user.hashed_password}" # ERROR


        if user.hashed_password == encrypt_password(password, user.salt)
            return user
        end
    end
end

def User.encrypt_password(password, salt)
    Digest::SHA2.hexdigest(password + "wibble" + salt)
end

def password=(password)
    @password = password
    if (password.present?)
        generate_salt
        self.hashed_password = self.class.encrypt_password(password, salt)
    end
end


private

    def password_must_be_present
        errors.add(:password, "Mot de passe manquant") unless hashed_password.present?
    end

    def generate_salt
        self.salt = self.object_id.to_s + rand.to_s
    end

end


User.where(:username => name) is returning an ActiveRecord::Relation object (hence the error message you are seeing). Try changing your if statement to:

if user = User.where(:username => name).first

That will set take the first matching user, which will be an instance of User and so will have a hashed_password field. If no user matches, you'll get nil.


put this in your model

   private
    def self.hash_password(password)
       Digest::SHA1.hexdigest(password)
    end 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜