Reputation: 2078
I'm trying to learn and use my own user model and authentication with Ruby on Rails 4.0, but most tutorials (if not all) seem to be outdated with this recent update. No method described on any of them works. I'm absolutely clueless, this is my User model:
class User
include Mongoid::Document
field :login, type: String
field :hash, type: String
field :salt, type: String
field :email, type: String
field :name, type: String
before_save :hash_password
validate :login, presence: true, uniqueness: true, length: { in: 4..24 }
validate :password, presence: true, confirmation: true, length: { in: 8..32 }
validate :email, presence: true
validate :name, presence: true
def hash_password
if password.present?
self.salt = BCrypt::Engine.generate_salt
self.hash = BCrypt::Engine.hash_secret(password, salt)
end
end
end
And the controller:
class UsersController < ApplicationController
def create
@user = User.new(user_params)
if @user.save
redirect_to @user
else
render 'new'
end
end
def new
@user = User.new
end
private
def user_params
params.require(:user).permit(:login, :password, :password_confirmation, :email, :name)
end
end
I then get an UnknownAttribute
error when I save the user. What am I missing? What fields are wrong?
Upvotes: 0
Views: 1844
Reputation: 2078
I managed to make it work. I didn't figure out what was the matter with the "unknown attribute" error, but I changed the model to use the method has_secure_password
, which automagically takes my :password
and :password_confirmed
parameters, bcrypts and save to :password_digest
field.
class User
include Mongoid::Document
include ActiveModel::SecurePassword # important, imports has_secure_password
field :login, type: String
field :password_digest, type: String
has_secure_password
field :email, type: String
field :name, type: String
validate :login, presence: true, uniqueness: true, length: { in: 4..24 }
validate :password, presence: true, confirmation: true, length: { in: 8..32 }
validate :email, presence: true, uniqueness: true
validate :name, presence: true
end
This done, I got the following error:
can't activate bcrypt-ruby (~> 3.0.0), already activated bcrypt-ruby-3.1.2. Make sure all dependencies are added to Gemfile.
Even though bcrypt was correctly added to my Gemfile, apparently has_secure_password
needs specifically version 3.0.x of the gem, so I forced it:
gem 'bcrypt-ruby', '~> 3.0.0'
This downloaded the version 3.0.1 (not 3.0.0) which worked as expected. I hope they fix this version incompatibility soon.
Thanks for all the answers. This project will be available open source when I finish :)
Upvotes: 1
Reputation: 9173
You can follow rail casts episode. I know its a bit old but i also used it a couple of months ago and for the rails 4 you can simply "permit" the attributes rather than using "attr_accessible" as rails 4 doesn't support attr_accessible.
Upvotes: 1
Reputation: 2564
You need to add:
attr_accessor :password
Right now you are trying to use the password attribute but rails doesn't know anything about it. attr_accessor
allows you to use the password attribute locally, but will not persist it to the database (which is good).
Upvotes: 1