如何序列化ActiveModel错误以供以后翻译?

时间:2013-01-02 17:11:38

标签: ruby-on-rails serialization internationalization jobs

我遇到一种情况,即用户将一些数据提交给将在后台处理的Web服务器(Rails):

POST /fibonacci/6012 HTTP/1.1
Host: example.com

服务器响应后台作业的链接,用户可以使用该链接检查状态:

HTTP/1.1 202 Accepted
Location: http://example.com/jobs/5699121

需要注意的重要一点是任何(授权)用户都可以检查作业的状态。这意味着我必须将工作者的任何错误消息传递回Web服务器符号。我无法找到一种方法来解决ActiveModel错误。例如:

class FibonacciCalculation
  include ActiveModel::Validations

  attr_reader :input
  validates_presence_of :input
  validates_inclusion_of :input, :in => 0..10_000,
                                 :allow_blank => true

  def initialize(params = {})
    @input = params[:input]
  end

  def output
    # do fibonacci calculation
  end
end

如果我使用FibonacciCalculation.new(:input => -5)创建这样的对象然后弄出错误,我会得到一个ActiveModel::Errors对象,但我无法弄清楚如何序列化它。要求errors[:input]给我["can't be blank"]["is not included in the list"],这些已经翻译过来。同样,errors.as_json会返回类似

的内容
`{ "errors" => [ "can't be blank" ] }`

我如何获得{ :input => [:blank] }{ :input => [:inclusion] }

之类的内容

2 个答案:

答案 0 :(得分:3)

ActiveModel::Errors会在添加错误后立即进行翻译,并且不会以符号方式存储密钥。这留下了两种方法来恢复数据:

1。猴修补

ActiveModel::Errors.class_eval do
  old_generate_message = instance_method(:generate_message)
  def generate_message(attribute, type = :invalid, options = {})
    options[:type] ||
      old_generate_message.bind(self).call(attribute, type, options)
  end
end

2。覆盖翻译

en:
  activerecord:
    errors:
      messages:
        blank: blank
        inclusion: inclusion
        ...

这两种情况对我来说都很棘手,因为相同的代码库同时运行工作者和Web服务器。因此,我必须有条件地加载猴子补丁或翻译覆盖。

答案 1 :(得分:0)

我遇到了同样的问题,我创建了一个小宝石来处理这个案例,希望这会对某人有所帮助:https://github.com/Intrepidd/activemodel_errors_type

您可以在翻译之前致电model.errors.with_types以获取错误类型。