【问题标题】:Is there a way to return error code in addition to error message in rails active record validation?除了rails活动记录验证中的错误消息之外,还有没有办法返回错误代码?
【发布时间】:2013-11-09 11:13:26
【问题描述】:

在rails activerecord验证中,通常如果验证失败,会在模型的errors属性中添加错误消息,但是我们的客户要求除了错误消息之外还返回错误代码,例如,我们有一个Bill模型,其中有一个msisdn属性,如果msisdn为null,则错误码为101,如果msisdn不符合MSISDN格式,则错误码为102,当客户端通过REST接口提交请求时,如果验证失败,我们应该返回一个类似的json对象

bill: {
    error_code: 101,
    error_message: "msisdn can't be null"
}

除了错误消息之外,有没有办法告诉 activerecord 生成错误代码?非常感谢。

【问题讨论】:

    标签: ruby-on-rails validation activerecord error-code


    【解决方案1】:

    errors只是一个普通的hash,key代表有错误的属性,value代表错误信息。因此,从技术上讲,您的要求可以通过用哈希替换文本消息来实现。但缺点是您可能需要做更多的事情才能以新格式显示错误。

    例如,使用自定义验证器添加错误代码

    class Foo < ActiveRecord::Base
      attr_accessible :msiisnd
      validate :msiisdn_can_not_be_blank
    
      def msiisdn_can_not_be_blank
        if msiisdn.blank?
          errors.add(:msiisdn, {code: 101, message: "cannot be blank"})
        end
      end
    end
    

    那就用吧

    foo = Foo.new
    foo.errors.count
    #=> 0
    foo.valid?
    #=> false
    foo.errors.count
    #=> 1
    foo.errors[:msiisdn]
    #=> [{ code: 101, message: "can not be blank"}]
    foo.errors[:msiisdn][0][:code]
    #=> 101
    

    所以你可以使用它。但是当您需要正确显示错误时,您需要做更多的工作,比如在表单中显示错误,因为这不是惯例。

    【讨论】:

    • 首先想到的是full_messages要坏了
    【解决方案2】:

    Rails 5 将包含与foo.errors.details 类似的功能。您可以轻松地使用它来构建更好的 api 错误。

    class Person < ActiveRecord::Base
     validates :name, presence: true
    end
    
    person = Person.new
    person.valid?
    person.errors.details
    # => {name: [{error: :blank}]}
    

    如果您更喜欢将代码错误作为数字,您可以轻松地将数字与错误键匹配。

    对于 Rails 3 和 4,您可以使用这个 gem https://github.com/cowbell/active_model-errors_details 女巫与向后移植的功能完全相同。

    【讨论】:

      【解决方案3】:

      Rails 5+ 或 Rails 4 和 active_model-errors_details gem:

      class User
        include ActiveModel::Model
        validate :forbid_special_email
        attr_accessor :email
      
        private
      
        def forbid_special_email
          errors.add(:email, 'is forbidden', code: 1234) if email == 'john@example.com'
        end
      end
      
      user = User.new(email: 'john@example.com')
      user.validate
      user.errors.full_messages # ["Email is forbidden"]
      user.errors.details # {:email=>[{:error=>"is forbidden", :code=>1234}]}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-10
        • 1970-01-01
        • 2020-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多