`
yangzhihuan
  • 浏览: 165371 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

如何自定义处理ActiveRecord中的errors信息

阅读更多
今天写代码的时候,客服MM向我反馈了一个问题,这个问题本身是很容易解决的,但是出现这个问题时的提示信息有些令人郁闷,ActiveRecord的信息显示在页面时,只看到了一堆I18n无法找到相应语言下定义的提示信息。

但是我的应用支持中文和英文,我仔细检查了locales下的en.yml和zh-CN.yml,明明是有配置相应的提示信息的,却显示无法找到。一番检查之后,我认为问题在于文件加载先后顺序的地方出事了,提示信息,我是在类定义中写的,如下:
class EntryAttachment < Attachment
  #不如惊讶,这是paperclip的方法
  has_attached_file :archives,
    :styles => { :p720x540 => '720x540>', :p120x90 => '120x90#', :p240x180 => '240x180#' }

  #问题就出在这里了,这是在类定义的时候调用了 I18n,但是有可能在类定义的时候,Rails并没有加载 i18n 的yml资源文件
  validates_attachment_size :archives, :less_than => 500.kilobytes,:message => I18n.t('attachments.validate.entry.size')
  validates_attachment_content_type :archives, :content_type => ['image/png', 'image/x-png'],:message => I18n.t('attachments.validate.entry.content_type')
end


在development模式下,是可以正常工作的,在production模式下则会出现找不到相应语言的提示信息,但是不要忘记了 development 模式是热部署的,所有文件都会预加载,并且一旦修改,会立即加载的。

所以的这里的问题,就是在类定义的时候调用  I18n ,但是 I18n 的资源文件还没有加载,当然就无法找到相应语言的信息了。

同样地,我无法在类定义的时候就知道 locale ,I18n 的locale只能在运行的时候,根据不同的请求来判断是英文还是中文,然后设置 I18n.locale = ‘en' or 'zh-CN'

===============================
我用了一个比较笨的方法去替换掉 @obj.errors 的信息(当这两个验证 validates_attachment_size,validates_attachment_content_type 不通过时,错误信息会自动加到 @obj.errors 中去,这是标准的ActiveRecord使用方法)

在controller 中判断 @obj.errors 中是否含有 validates_attachment_size,validates_attachment_content_type 这两个验证的key,然后进行替换,但是 AcitveRecord::Errors比较白痴的是,没有提供remove某一个错误信息的方法,只能有一个 clear (全部清除)的方法,实现如下:
      errors = []
      @entry.errors.each do |attr,msg|
        errors << [attr,msg]
      end
      @entry.errors.clear
      errors.each do |i|
        if i[0] == 'attachments.archives_file_size'.to_sym
          @entry.errors.add_to_base I18n.t('attachments.validate.entry.size')
        elsif i[0] == 'attachments.archives_content_type'.to_sym
          @entry.errors.add_to_base I18n.t('attachments.validate.entry.content_type')
        else
          @entry.errors.add i[0],i[1]
        end
      end

这段代码写得比较烂了,不过它是有用的。
分享到:
评论
3 楼 ybffnst 2011-09-14  
paperclip 对错误消息的处理是对字符串进行处理的,不支持symbol
所以在messages下自定义错误消息是行不通的,可以通过在full_messages下添加自定义信息进行处理。
2 楼 yangzhihuan 2011-07-27  
@ssword 你这么一说,我猛然醒悟了,我靠,根本就忘记了i18n的本意了,我土鳖了。
1 楼 ssword 2011-07-27  
rails在输出error时似乎会自己调用locale的,只要修改自己的locale,像这样

  activerecord:
    attributes:
      user:
        homepage: "主页"
        description: "简介"
        email: "邮箱"
        password: "密码"
        name: "昵称"
    errors:
      template: # ~ 2.3.5 backward compatible
        header:
          one: "有 1 个错误发生导致「%{model}」无法被保存。"
          other: "有 %{count} 个错误发生导致「%{model}」无法被保存。"
        body: "如下字段出现错误:"
      full_messages:
        format: "%{attribute} %{message}"
      messages:
        ...
        taken: "已经被使用"
        record_invalid: "校验失败: %{errors}"

在message这列下面加上自定义的错误信息即可,而在 :message => 中不需要显式调用I18n.t就可以的

http://blog.ashchan.com/archive/2008/11/24/rails-i18n-activerecord-model-human-name-made-easy/

相关推荐

Global site tag (gtag.js) - Google Analytics