undefined method `min_cost' for ActiveModel::SecurePassword:Module

640 Views Asked by At

I am following Michale harlt's ruby on rails tutorial.Everything was going fine uptill I got stuck into this problem in which after giving user name and password and clicking on "Login" push button and I am getting an error "undefined method `min_cost' for ActiveModel::SecurePassword:Module".I am trying to resolve this issue from last 2 days but could'nt able to find any relevant solution. Please help me to solve this.Thanks in advance.Here are all my relevant files of project. (I am using rails 3.2.16) For any further information please let me know.

user.rb

class User < ActiveRecord::Base
attr_accessor :remember_token
before_save { self.email = email.downcase }
validates :name,  presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
                format: { with: VALID_EMAIL_REGEX },
                uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }

# Returns the hash digest of the given string.
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                 BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end

# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end

# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end

# Returns true if the given token matches the digest.
def authenticated?(remember_token)
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
end

sessions_helper.rb

module SessionsHelper

# Logs in the given user.
def log_in(user)
 session[:user_id] = user.id
 end

 # Remembers a user in a persistent session.
 def remember(user)
 user.remember
 cookies.permanent.signed[:user_id] = user.id
 cookies.permanent[:remember_token] = user.remember_token
 end

 # Returns the user corresponding to the remember token cookie.
 def current_user
  if (user_id = session[:user_id])
  @current_user ||= User.find_by_id(user_id)
  elsif (user_id = cookies.signed[:user_id])
  user = User.find_by_id(user_id)
  if user && user.authenticated?(cookies[:remember_token])
    log_in user
    @current_user = user
  end
  end
  end

  # Returns true if the user is logged in, false otherwise.
  def logged_in?
  !current_user.nil?
  end

  # Log Out Current User
  def log_out
   session.delete(:user_id)
   @current_user = nil
   end
  end

sessions_controller.rb

    class SessionsController < ApplicationController

   def new
   end

   def create
   user = User.find_by_email(params[:session][:email].downcase)
   if user && user.authenticate(params[:session][:password])
   log_in user
   remember user
   redirect_to user
   else
   flash.now[:danger] = 'Invalid email/password combination'
   render 'new'
   end
end

  def destroy
  log_out
  redirect_to home_path
  end
end

GemFile

    source 'https://rubygems.org'

gem 'rails', '3.2.16'
    gem 'bcrypt-ruby', '~> 3.1.2'
    gem 'strong_parameters'



    # Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

group :development, :test do    
  gem 'sqlite3',     '1.3.9'
      gem 'guard'


     end

group :test do
  gem 'minitest-reporters'   
  gem 'mini_backtrace',     '0.1.3'
  gem 'guard-minitest',     '2.3.1'
end

group :production do
  gem 'pg',             '0.17.1'
  gem 'rails_12factor', '0.0.2'
      gem 'puma',           '2.11.1'

end


# Gems used only for assets and not required
# in production environments by default.
group :assets do

  gem 'coffee-rails', '~> 3.2.1'
      gem 'sass-rails', '>= 3.2'
      gem 'bootstrap-sass', '~> 3.3.4'
      gem 'sprockets-rails', '=2.0.0.backport1'
      gem 'sprockets', github: 'tessi/sprockets', branch: '2_2_2_backport2'


  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem 'therubyracer', :platforms => :ruby

  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'

# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# To use Jbuilder templates for JSON
# gem 'jbuilder'

# Use unicorn as the app server
# gem 'unicorn'

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'debugger'

Application Trace

    app/models/user.rb:14:in `digest'
    app/models/user.rb:27:in `remember'
    app/helpers/sessions_helper.rb:10:in `remember'
    app/controllers/sessions_controller.rb:10:in `create'        
1

There are 1 best solutions below

2
On BEST ANSWER

As far as I remember, SecurePassword#min_cost appeared in rails4 (or in rails3 > 3.2.16.)

Since you are just learning, my advice would be not to concentrate on solving this particular error, but just substitute the problematic line with:

cost = BCrypt::Engine::MIN_COST

or even with

cost = 10

and go further. Whether you are still to fix this, you should upgrade your rails up to 4 (or whatever version this method was introduced.)