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'
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:
or even with
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.)