13

在 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 生成错误代码?非常感谢。

4

3 回答 3

9

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女巫是完全相同的功能向后移植。

于 2016-05-26T13:35:46.110 回答
4

errors只是一个普通的哈希,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

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

于 2013-10-30T03:33:38.170 回答
1

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}]}
于 2018-04-10T17:29:11.803 回答