Is there a way to return error code in addition to error message in rails active record validation?

后端 未结 3 1817
孤城傲影
孤城傲影 2021-02-05 16:04

In rails activerecord validation, normally if a validation fails, it will add an error message in the errors attribute of models, however our clients demands an error code be re

相关标签:
3条回答
  • 2021-02-05 16:50

    errors is just a plain hash, with the key represents the attribute which has an error, and the value represents the error message. So technically your requirement is doable by replacing the text message with a hash. But the downside is you may need to do more things to show the errors in new format.

    For example, use a custom validator to add error code

    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
    

    Then use it

    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
    

    So you can use it. But you need to do more work when you need to show the errors correctly, say displaying errors in a form, as this is not a convention.

    0 讨论(0)
  • 2021-02-05 17:02

    Rails 5 will include a similar feature with foo.errors.details. You can easily use this to build better api errors.

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

    If you prefer code errors as numbers, you can easily match numbers with the error keys.

    For Rails 3 & 4 you can use this gem https://github.com/cowbell/active_model-errors_details witch is the exact same feature backported.

    0 讨论(0)
  • 2021-02-05 17:09

    Rails 5+ or Rails 4 and 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}]}
    
    0 讨论(0)
提交回复
热议问题