I've tried looking at previous questions and answers regarding this error, but the solutions didn't seem to work for me. The error is thrown on the line:
if customer && customer.authenticate(params[:session][:password_digest])
I am able to Sign Up a user (under a company) and sign up a company, but I get this BCrypt error whenever I try to log a user in. I only started using the has_secure_password stuff etc once my user model and company model etc. were in place, I just realised later that it was silly to not protect passwords. Even if I create a new user now, I still get this error logging on.
I think this might be due to my relationships of my Users? (maybe completely not, I am very new to Ruby!) My users belong to a company (many to one), and when they sign up they choose a company from a list in order to be listed under it in the database. Here is my code relating to this error:
class SessionsController < ApplicationController
def new
end
def create
customer = Customer.find_by_email(params[:session][:email])
if customer && customer.authenticate(params[:session][:password_digest])
log_in customer #see sessions helper
remember customer #see sessions helper
redirect_to '/main'
else
redirect_to '/login'
end
end
def destroy
#session[:user_id] = nil
forget(current_customer)
session.delete(:customer_id)
@current_customer = nil
redirect_to '/'
end
end
class CreateCustomers < ActiveRecord::Migration
def change
create_table :customers do |t|
t.timestamps
t.references :business, foreign_key: true
t.timestamps
t.string :first_name
t.string :last_name
t.string :email
t.string :password_digest
t.string :remember_digest
t.string :role
end
end
end
class CustomersController < ApplicationController
def new
@customer = Customer.new
@businesses = Business.all
end
def create
@customer = Customer.create(customer_params)
@customer.save!
session[:customer_id] = @customer.id
redirect_to '/'
rescue ActiveRecord::RecordInvalid => ex
render action: 'new', alert: ex.message
end
private
def customer_params
params.require(:customer).permit(:first_name, :last_name, :business_no, :email, :password_digest, :business_id) #replace company with company ID
end
end
Please help me, I'm tearing my hair out :(
The error you're getting probably means that the password_digest
stored for that user is invalid for some reason (empty perhaps).
Enter a rails console: rails console
and execute the following:
u = User.find_by(email: "your_user_email")
puts u.password_digest
and see what the output is.
(also as mentioned in a comment on your question, you should use the plain text password when you use the authenticate method)
You shouldn't use the password_digest
attribute directly, instead there are two attributes you should be using: password
and password_confirmation
(these attributes become available to you automatically when you use has_secure_password
, so you don't need to define them).
So in your controller, instead of this:
params.require(:customer).permit(:first_name, :last_name, :business_no, :email, :password_digest, :business_id) #replace company with company ID
You should have:
params.require(:customer).permit(:first_name, :last_name, :business_no, :email, :password, :password_confirmation :business_id) #replace company with company ID
and edit your form accordingly to provide inputs for password
and password_confirmation
.
Now when you create your object using these params, it will automatically assign the password digest into password_digest
by encrypting the clear text contained in password
and password_confirmation
.