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

时间:2011-04-23 03:45:42

标签: ruby-on-rails validation devise

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

当用户尝试编辑他们的帐户信息时出现了问题,因为它找到了:同意验证,但我能够添加一个'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

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

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

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

3 个答案:

答案 0 :(得分:12)

那么,您需要在创建记录时验证术语的接受度吗?

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

:on => :create只会在创建记录时执行该验证 - 就像Brandon的答案一样,但没有冗余代码。

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

答案 1 :(得分:3)

我更倾向于根据记录是否为新记录(这是用户“注册”的唯一时间)。

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的值是“要调用的方法,过程或字符串,以确定是否应该[或不应该]进行验证” - 所以你可以自由地为你的模型定义方法。

答案 2 :(得分:0)

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

请在此处查看我的回答:

Validation errors are triggered when I'm trying to reset password