覆盖来自Gems /插件的Rails错误(验证)消息

时间:2010-01-11 16:18:59

标签: ruby-on-rails validation rubygems

是否有一种普遍接受的方法可以覆盖来自rails中的gem / plugin的错误(验证)消息?

例如,我正在使用ActiveMerchant宝石,如果有人输入美国运通信用卡号,但选择“万事达卡”,我会得到一个不太具描述性的“类型不是正确的卡片输入“错误。

我可以通过这样的方式轻松解决这个问题:

def validate_card
  unless credit_card.valid?
    credit_card.errors.full_messages.each do |message|
      if message =~ /is not the correct card type/i
        errors.add_to_base "This credit card number is invalid. 
                            Please ensure that you selected the correct type."
      else
        errors.add_to_base message
      end
    end
  end
end

但是这种技术很快变得不可维护,并且显然(至少在我看来)远离“最佳实践”。

同样,我可以解压缩ActiveMerchant gem并将其破解以输入我自己的自定义错误消息,但这似乎也无法维护,因为它需要将相同的hack添加到未来的,未解压缩的ActiveMerchant版本中。

1 个答案:

答案 0 :(得分:1)

老实说,最好的办法是重写部分gem /插件以满足您的需求。不幸的是,如果您决定随时更新gem /插件,您将失去更改。

但是,Ruby是一种动态语言,因此可以重新打开类,并且可以从任何文件覆盖任何模块/类的方法。通过开源的魔力,我已经找到了你需要干预的模块/类/方法,以实现你的目标。

将以下内容放入文件中并确保在ActiveMerchant之后加载(如何加载它取决于您使用的是插件还是gem)

module ActiveMerchant
  module Billing
    class CreditCard

      private
      def validate_card_number #:nodoc:
        errors.add_to_base "This credit card number is invalid. \n" +
         "Please ensure that you selected the correct type." unless 
            CreditCard.valid_number?(number)
      end
    end
  end
end

N.B。:此方法依赖于ActiveMerchant内部,这通常是一个坏主意。但我认为维护自己版本的ActiveMerchant是两个邪恶中较小的一个。如果您更新gem /插件以及上面代码所依赖的内容已经改变,它可能会以奇怪的方式中断。