Ruby on Rails / Devise – 在重置密码时绕过模型中的自定义validation选项

在我的项目中,我修改了Devise中的注册表单,通过访问者添加:agree选项(用户必须接受注册的服务条款等)。 如果他们不同意,则不会进行validation。

当用户试图编辑他们的帐户信息时,这导致了一个问题,因为它找到了:同意validation,但我能够添加一个’unless’子句并添加另一个名为:signed_in的访问器,它在控制器中定义(我无法’弄清楚如何让模型确定用户是否已登录,设计的助手对我来说不起作用)。 我的User模型和users_controller的相关部分看起来像……

user.rb

validates :agree, :term_agreement => TRUE, :unless => :signed_in 

users_controller.rb

 def update @user = User.find(params[:id]) if user_signed_in? @user.signed_in = params[:user] end [...] end 

所以,一切正常……当用户已经登录时,“同意”validation会覆盖。但是,我必须找出覆盖其他方案的最佳方法…当用户重置密码并需要更改时它。

我正在测试用户帐户,并试图在一个帐户上重置我的密码,但是我遇到了:同意validation…现在我必须找到一种方法来覆盖它。 我注意到更改密码表单的隐藏字段值为:reset_password_token,但我尝试过:除非=>:reset_password_token但它不起作用。

那么实现这个目标的最佳方法是什么? 除此之外,我怎么能有一个/或条件(除非:signed_in或:reset_password等):except子句?

那么,您需要在创建记录时validation术语的接受程度?

 class User < ActiveRecord::Base validates :agree, :acceptance => true, :on => :create end 

:on => :create只会在创建记录时执行该validation – 很像Brandon的答案,但没有冗余代码。

这也可以避免您的控制器担心用户是否已登录。

我更喜欢根据记录是否是新的(这是用户“注册”的唯一时间)来确定这些事情。

 class User < ActiveRecord::Base validates :agree, :term_agreement => TRUE, :if => :signing_up? # Return true if the user is currently signing up def signing_up? new_record? end end 

关键是要记住:if:unless的值是“要调用的方法,proc或字符串,以确定validation是否[或不应该]发生” – 所以你可以自由定义方法你的模型用于此目的。

我通过配置devise来修复此问题,以便在validation失败时更新密码属性,但前提是密码属性没有错误。

在这里看到我的答案:

我在尝试重置密码时会触发validation错误