我正在开发一个Rails 2.3.14项目,该项目使用0.6.0的i18n gem和2.3.14的ActiveSupport gem。这两个方法都定义了Hash#slice
方法(i18n's; ActiveSupport's),但它们的功能不同:i18n版本使用Hash#fetch
,因此会引发i18n/core_ext/hash.rb:4:in 'fetch': key not found (IndexError)
异常如果缺少任何请求的密钥,而ActiveSupport版本很乐意忽略丢失的密钥,而ActiveSupport的其余部分则依赖于那个快乐的忽略。
在我的应用程序中,i18n版本首先加载(因为,顺便说一句,faker正在加载它作为依赖项),因此当ActiveSupport尝试依赖ignore-missing-keys行为时,我得到了异常。
有没有办法告诉Rails在faker和i18n之前加载ActiveSupport?
答案 0 :(得分:1)
您还可以在需要宝石后对Hash类进行修补。您可以将ActiveSupport的hash / slice.rb的内容粘贴到您的应用程序中。 URL可以在这里找到:
https://github.com/lifo/docrails/blob/master/activesupport/lib/active_support/core_ext/hash/slice.rb
那会覆盖宝石的定义,所以YMMV。
答案 1 :(得分:1)
我使用@Eugene的想法恢复到ActiveSupport的方法(因此他获得了快乐的绿色复选标记),但是这样做是为了避免重复代码。首先我们测试一下我们是否正在使用i18n版本,如果我们使用remove_method
来擦除它(通过打开类添加它)并让ActiveSupport 2.3.14模块填写(注意我没有使用undef
,这也消除了模块的覆盖。)
因此,在初始化程序中输入代码:
begin
{}.slice(:a) # ActiveSupport's slice is fine with this; i18n's is not
rescue IndexError
class Hash
remove_method :slice #kill i18n's implementation, allow the ActiveSupport module to work
end
end
答案 2 :(得分:0)
如果您无法控制加载顺序,可以尝试使用此博文中的方法http://banisterfiend.wordpress.com/2010/11/04/baking-module-methods-into-classes-with-alias_method/
我已经习惯了,它对我有用,但那是我自己编写的模块。
答案 3 :(得分:0)
我在i18n项目上打开了一个问题,让切片更加安全,并创建了一个PR来实现它。您可以在https://github.com/svenfuchs/i18n/pull/292找到问题/公关。
要手动修补自己,您只需在获取后添加if has_key?(key)
。