【问题标题】:How do I tell *which* validator caused an error?如何判断 *which* 验证器导致错误?
【发布时间】:2015-05-19 16:38:43
【问题描述】:

我正在调试this problem with devise-- 尽管我尽了最大努力,但在不提供密码的情况下更新用户时仍然收到错误“密码不能为空”。我已经尝试过官方解决方案以及this SO question 中建议的解决方案,但尽管确保传递给 update_attributes 的 opts 不包含passwordpassword_confirmation,但我仍然收到错误消息。

我正试图弄清楚如何调试这个——我在 devise、activerecord、activemodel 等中四处寻找,但我似乎无法将调试语句准确地放在正确的位置。

当我运行User.validators 时,我得到以下输出:

=> [#<ActiveRecord::Validations::PresenceValidator:0x007ff513507890 @attributes=[:email], @options={:if=>:email_required?}>,
 #<ActiveRecord::Validations::UniquenessValidator:0x007ff51350fef0
  @attributes=[:email],
  @klass=
   User(id: integer, name: string, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, school_id: integer, invitation_token: string, invitation_created_at: datetime, invitation_sent_at: datetime, invitation_accepted_at: datetime, invitation_limit: integer, invited_by_id: integer, invited_by_type: string, type: string, opt_in: boolean),
  @options={:case_sensitive=>true, :allow_blank=>true, :if=>:email_changed?}>,
 #<ActiveModel::Validations::FormatValidator:0x007ff51351c560
  @attributes=[:email],
  @options={:with=>/\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/, :allow_blank=>true, :if=>:email_changed?}>,
 #<ActiveRecord::Validations::PresenceValidator:0x007ff5148e4b60 @attributes=[:password], @options={:if=>:password_required?}>,
 #<ActiveModel::Validations::ConfirmationValidator:0x007ff50efb85a0 @attributes=[:password], @options={:if=>:password_required?}>,
 #<ActiveModel::Validations::LengthValidator:0x007ff5150e91d0
  @attributes=[:password],
  @options={:allow_blank=>true, :minimum=>8, :maximum=>128}>,
 #<ActiveRecord::Validations::PresenceValidator:0x007ff515125a90 @attributes=[:name], @options={}>]

Devise 本身(理论上)足够聪明,如果您没有更改密码,就不会要求输入密码:

devise/lib/devise/models/validatable.rb

validates_presence_of     :password, if: :password_required?
validates_confirmation_of :password, if: :password_required?

# ... 
def password_required?
  !persisted? || !password.nil? || !password_confirmation.nil?
end

您可以看到这反映在上面的User.validators 检查中。

但是,我仍然收到此错误!

我如何追踪此错误被添加到对象的位置,以及是谁插入了有问题的验证器?

【问题讨论】:

  • 您是否通过编辑表单参数传递了任何空白密码字段?
  • @TarunJadhwani 是的,但我正在从传递给 update_attributes 的哈希中删除它。已经用调试器验证了这一点。唯一通过的是另一个属性 ({:opt_in: true})。

标签: ruby-on-rails ruby-on-rails-4 activerecord devise activemodel


【解决方案1】:

您是否在注册控制器中添加了以下代码?

class RegistrationsController < Devise::RegistrationsController

  protected

  def update_resource(resource, params)
    resource.update_without_password(params)
  end
end

还有routes.rb中的路由

devise_for :users, controllers: {registrations: 'registrations'}

【讨论】:

  • 我已经尝试了该设计 wiki 页面上列出的两种方法 - update_attributes 和 update_without_password 都无法绕过流氓验证器。我本身不需要解决问题的方法;我需要一个好的调试方法!
猜你喜欢
  • 2013-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 2013-01-17
  • 1970-01-01
  • 2019-01-28
相关资源
最近更新 更多