Reputation: 383
I am trying to hash a password using bcrypt-ruby and save it to a postgres users table but I cannot get the hash to save properly. Can someone tell me what I am doing wrong? This is what I have tried:
User Model:
require 'bcrypt'
class User < ApplicationRecord
include ActiveModel::SecurePassword
include BCrypt
has_secure_password
attr_accessor :password
attr_accessor :password_digest
enum :user_type, { :registered => 1, :administrator => 2 }
validates :email, presence: true
validates_format_of :email, with: URI::MailTo::EMAIL_REGEXP
validates :password_digest, presence: true
validates :password_confirmation, presence: true
end
Rails Migration:
class User < ActiveRecord::Migration[7.0]
create_table :users do |t|
t.string :username, null: false, default: ""
t.string :email, null: false, default: ""
t.string :password_digest, null: false, default: ""
t.string :user_type, default: 'registered'
t.timestamps null: false
end
add_index :users, :username, unique: true
add_index :users, :email, unique: true
add_index :users, :user_type
end
Rails Console:
include BCrypt
@user = User.new
@user.username = "test123456"
@user.email="[email protected]"
@user.user_type = 1
@user.password = "test123456"
@user.password_digest = Password.create("test123456")
@user.password_confirmation = "test123456"
@user.save!
Generated SQL in Rails Console:
TRANSACTION (0.2ms) BEGIN
User Create (0.4ms) INSERT INTO "users" ("username", "email", "password_digest", "user_type", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["username", "test123456"], ["email", "[email protected]"], ["password_digest", "[FILTERED]"], ["user_type", "1"], ["created_at", "2024-10-03 13:53:37.193227"], ["updated_at", "2024-10-03 13:53:37.193227"]]
TRANSACTION (0.8ms) COMMIT
Postgres:
Upvotes: 0
Views: 59
Reputation: 106782
You need to remove these two line from your User
model:
attr_accessor :password
attr_accessor :password_digest
Because those are overriding the getter and setter models that are created automatically by Ruby and Rails.
And I suggest changing
validates :password_confirmation, presence: true
to
validates :password_confirmation, presence: true, on: :create
Because the password_confirmation
is only set when the user sets or updates the password. When the user, for example, want to change their email, the password_confirmation
would be blank, because it is not stored to the DB.
Upvotes: 3