我正在从头开始练习一些Rails身份验证(sans Devise gem),但由于某种原因在实现ActiveModel::SecurePassword
时遇到了一些问题。如果我进入控制台,我可以创建一个新用户,看到所有的验证都得到了执行,如果我保存了一个新用户(例如user.save
),我会看到password_digest
设置成功。
但是,如果我通过我的用户注册表***创建一个新用户***,我的password_digest
每次都是nil
。有人知道为什么吗?我确信我的参数被接收到了,因为我可以在保存之前打印它们并查看它们。
关于上下文,我尝试了以下方法:
- 添加
ActiveModel::SecurePassword
到我的用户模型 - 已启用
bcrypt
gem并运行bundle install
- 如果我进入
irb
,我可以生成一个新的示例,就像这样,并看到password_digest
:
3.2.1 :137 > new_user = User.new(first_name: "test", last_name: "tester", email: "foo@bar.com", password: "123123123")
=> #<User:0x0000000107c5bf40 id: nil, first_name: "test", last_name: "tester", email: "foo@bar.com", password: nil, created_at: nil, updated_at: nil>
3.2.1 :138 > new_user.save
TRANSACTION (0.7ms) BEGIN
User Exists? (0.8ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "foo@bar.com"], ["LIMIT", 1]]
User Create (0.5ms) INSERT INTO "users" ("first_name", "last_name", "email", "password", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["first_name", "test"], ["last_name", "tester"], ["email", "foo@bar.com"], ["password", "[FILTERED]"], ["created_at", "2023-03-07 03:36:07.501992"], ["updated_at", "2023-03-07 03:36:07.501992"]]
TRANSACTION (1.3ms) COMMIT
=> true
3.2.1 :139 > new_user.password_digest
=> "$2a$12$aIcAuAdSnJhrLw0bWHTh1OgTTmUioB2ra3h12cFNs/IwnJdyRYJEW"
# NOTE:^ Successfully encrypts the password field via Bcrypt
但是,如果我运行注册表单,所有参数都是正确的,我得到这个字段的nil
。下面是从注册表单创建的最新用户的irb
打印输出:
3.2.1 :140 > latest_user = User.last
User Load (1.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<User:0x0000000107d75ca0 id: 27, first_name: "Allday", last_name: "Everyday", email: "allday@everyday.com", password: nil, created_at: Tue, 07 Mar 2023 03:39:13.986217000 UTC +00:00, updated_at: Tue, 07 Mar 2023 03:39:13.986217000 UTC +00:00>
3.2.1 :141 > latest_user.password_digest
=> nil
# NOTE: digest is `nil`!
以下是我当前的用户模型和user_controller.rb
逻辑,以供参考:
一米十三分一秒
# == Schema Information
#
# Table name: users
#
# id :bigint not null, primary key
# email :string
# first_name :string
# last_name :string
# password :string
# password_digest :string
# created_at :datetime not null
# updated_at :datetime not null
#
class User < ApplicationRecord
include ActiveModel::SecurePassword
has_secure_password
has_secure_password :recovery_password, validations: false
before_save :downcase_email
validates :email, format: {with: URI::MailTo::EMAIL_REGEXP}, uniqueness: true, presence: true
validates :first_name, length: {minimum: 2, maximum: 100}, presence: true
validates :last_name, length: {minimum: 2, maximum: 100}, presence: true
validates :password, length: {minimum: 8, maximum: 25}, presence: true
attr_accessor :password_digest, :recovery_password_digest
private
def downcase_email
self.email = email.downcase
end
end
这是我的控制器逻辑:
一米十四
class UserController < ApplicationController
# post '/user/register'
def create
user = User.new(user_params)
begin
user.save!
session[:user_id] = user.id
return render json: {success: true, status: 200}
rescue => exception
return render json: {success: false, status: 422, error: exception.message}
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
end
有人看到我做错了什么吗?或者有什么建议吗?为什么在通过控制器方法逻辑创建用户时password_digest
可能为null?非常感谢您的时间--在这个问题上被难倒了!
1条答案
按热度按时间qco9c6ql1#
从
app/models/user.rb
中删除此行因为
attr_accessor
创建的getter和setter方法将覆盖Ruby on Rails为数据库中的列自动创建的方法。