Rails 中的验证冲突
Posted
技术标签:
【中文标题】Rails 中的验证冲突【英文标题】:Validations conflicts in Rails 【发布时间】:2016-04-06 04:36:49 【问题描述】:我正在做一个项目,我遇到了一个我试图解决但没有进展的问题。
所有这些都是在我开始实现Forgot Password
重置密码功能时发生的。我有一个User Model
,它对password
和password_confirmation
进行了验证。我使用这些进行注册并且工作正常。
但是对于这个功能,我使用了一个名为PasswordResets
的新控制器。我正在为我的 users 表生成一个名为 password_reset_token
的字符串。还有password_reset_sent_at
,它记录了用户要求重置的时间。流程是这样的;
1) 用户点击
Forgot Password
?2) 他被重定向到要求他输入电子邮件的页面。
3) 控制器检查电子邮件是否存在于数据库中,如果存在则 ; 3.1) 我使用
SecureRandom
生成一个随机的password_token
以及他开始请求的时间。 3.2)现在保存在这里发送邮件给用户。这里出现了问题。password_reset_token
未保存到表中。
这背后的原因是我在User.rb
中使用password
和password _confirmation
的验证。这里发生的动作是:update
,所以更新记录要求password
和password_confirmation
与password_reset_token
和时间一起发送。
但我尝试通过将验证保留为:on => :create
来解决问题,现在它运行良好,但是当我使用链接重置时,我的验证不适用于password
和password_confirmation
。这对我来说就像一个僵局。我知道这有点令人困惑,我正在粘贴一些代码来理解问题。
我的PasswordResets Controller
创建操作:
def create
user= User.find_by_email(params[:email])
if user
user.send_password_reset
UserMailer.password_reset(self).deliver
flash[:success] = "Email sent with password reset instructions."
redirect_to root_url
else
flash[:error] = "Email doesn't exit."
render 'password_resets/new'
end
end
我的User Model
(user.rb)
class User < ActiveRecord::Base
has_secure_password
EMAIL_REGEX = /\A[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]2,4\Z/i
validates_confirmation_of :password_confirmation
validates :username, :presence => true,
:uniqueness => true,
:length => :within => 8..25
validates :email, :presence => true,
:uniqueness => true,
:format => EMAIL_REGEX
validates :password, :length => :within => 8..25
validates :password_confirmation, :presence => true
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
end
错误在send_password_reset
中显示在save!
。我附上一张图片。
我知道问题可以通过使用:on=>:create
进行验证来解决,因为:update
请求正在发生。但是当我在控制台中获得确认链接并使用它时,密码和密码确认的验证不起作用,因为这里的操作是:update
。这就像一个僵局。
我真的很感谢任何帮助我走出这个迷宫的人。
谢谢。
【问题讨论】:
【参考方案1】:您可以使用以下示例跳过验证。
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
self.save(validate: false)
UserMailer.password_reset(self).deliver
end
【讨论】:
以上是关于Rails 中的验证冲突的主要内容,如果未能解决你的问题,请参考以下文章
Rails 中的 Authorize.net - 由于身份验证值无效,用户身份验证失败
如何在路由级别验证 Rails 中的 restful 参数?
graphql_devise 用于 Rails/Graphql/Apollo/React 中的身份验证。 “字段需要身份验证”错误