【问题标题】:Rails distinct validationsRails 不同的验证
【发布时间】:2015-11-13 12:28:06
【问题描述】:

如何区分哪个验证器失败了?

我在同一个字段上有多个验证:

class User < ActiveRecord::Base
     validates :name, presence: true, length: {minimum: 1, maximum: 20 }
     validates_uniqueness_of :name
end

当我将用户保存为 user.save - 我想区分失败的原因。

if user.__not_valid_name_length__?
    # name length wrong
    # do smth 1
end
if **user.__not_valid_name_unique__?
    # name is not unique
    # do smth 2
end

我可以访问 user.errors[:name] 并查看该字段的所有错误消息。 但我不想依赖可以更改的消息文本。

有没有办法知道哪个验证器失败了?

【问题讨论】:

    标签: ruby-on-rails validation


    【解决方案1】:

    一个返回机器可解析符号而不是字符串的功能几乎是一年前提交给 Rails 的,但它在 4-x-stable 分支中仍然不可用。如果你使用边缘版本,你可以使用它,它将在 Rails 5 中可用。

    例子:

    user = User.new
    user.valid?
    user.errors.details[:name] # returns: [{error: :blank}, {error: :too_short}]
    

    更多信息:

    https://github.com/rails/rails/pull/18322

    https://github.com/rails/rails/blob/master/activemodel/lib/active_model/errors.rb

    【讨论】:

    • 你知道这在 4.2.5 中是否可用吗?还是肯定只有第 5 版?
    • 我相信在 Rails 5 之前它不会可用,至少现在它还没有合并到 rails-4-2-stable 分支中。
    • 同时,如果您将其作为 gem 包含,您可以使用它:github.com/cowbell/active_model-errors_details
    【解决方案2】:

    没有用于rails验证失败的内置回调,对于rails验证可用的回调是:

    • before_validation

    • after_validation

    要了解更多关于回调的信息,请阅读call_back

    根据消息检查验证失败不是好方法。它可能会在不同的情况下发生变化,即国际化。通过定义method for validation 来做到这一点,即

    # check presence_of validation
    
    def is_name_present?
      self.name.present?
    end
    
    # check uniqueness validation
    
    def is_name_uniqe?
      User.where(name: self.name).count == 0
    end
    

    使用最适合你的,我建议使用after_validation

    after_validation :post_validatiom
    
    def post_validation
      unless is_name_present?
        # do_someting
      end
    
      unless is_name_uniqe?
        # do_something
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多