2010-01-11 51 views
1

是否有一种通用的方式来覆盖来自rails中gem/plugin的错误(验证)消息?重写Rails错误(验证)来自Gems /插件的消息

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

我可以很容易地解决这个获得通过做这样的事情:

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并将其加载到我自己的自定义错误消息中,但这似乎也不可维护,因为它需要将相同的黑客添加到未打包的ActiveMerchant版本中。

回答

1

诚实地说,最好的办法是重写gem/plugin的部分内容以满足您的需求。不幸的是,如果你决定随时更新gem/plugin,你将会失去你的改变。

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

将下面的文件,并确保它得到ActiveMerchant后加载(如何加载它依赖于你是否正在使用的插件或宝石)

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 

注:这种方法依赖在ActiveMerchant内部,这通常是一个坏主意。但我认为它是维护自己版本的ActiveMerchant的两个弊端中的一个。如果你更新gem/plugin和上面的代码依赖的东西已经改变,它可能会以奇怪的方式打破。

+0

谢谢,我曾想过做这样的事情,但不确定'validate_card_number'是否是私人的事实会导致任何问题。 – jerhinesmith 2010-01-11 18:36:27