Wie man den Namen Kollision zwischen I18Ns Hash#Slice und ActivesuPPorts Hash#Slice behebt
-
27-10-2019 - |
Frage
Ich arbeite an einem Rails 2.3.14 -Projekt, bei dem 0,6,0 der verwendet werden I18n Edelstein und 2.3.14 des Activesupport -Gems. Beide definieren a Hash#slice
Methode (i18ns; Activesupports), aber sie funktionieren anders: Die i18n -Version verwendet Hash#fetch
, und so groß i18n/core_ext/hash.rb:4:in 'fetch': key not found (IndexError)
Ausnahme, wenn ein angeforderter Schlüssel fehlt, während die Activesupport -Version fehlende Schlüssel glücklich ignoriert und der Rest von Activesupport von diesem glücklichen Ignorieren abhängt.
In meiner App wird die i18n-Version zuerst geladen (da Faker sie übrigens als Abhängigkeit lädt). Wenn Activesupport versucht, sich von dem Verhalten von Ignore-Missing-Keys zu verlassen, bekomme ich die Ausnahme.
Gibt es eine Möglichkeit, die Rails vor Faker und I18N zu sagen, dass sie Activesupport laden sollen?
Lösung
Sie können auch die Hash -Klasse nach der benötigten Hash -Klasse patchen. Sie können einfach den Inhalt der Hash/Slice.RB von Activesupport in Ihre App in Ihre App einfügen. Die URL kann hier gefunden werden:
https://github.com/lifo/docrails/blob/master/activesupport/lib/active_support/core_ext/hash/slice.rb
Das würde jedoch die Definitionen aus den Edelsteinen außer Kraft setzen, also ymmv.
Andere Tipps
Ich habe @Eugenes Idee verwendet, zu ActivesUpTs Methode zurückzukehren (und so erhält er das Happy Green Checkmark), hat es aber so getan, wie es vermieden wird, den Code zu duplizieren. Zuerst testen wir, um zu sehen, ob wir die i18n -Version verwenden und ob wir es sind remove_method
Um es auszulöschen (es wurde hinzugefügt, indem die Klasse geöffnet wird) und das Activesupport 2.3.14 -Modul ausfüllen lassen (beachten Sie, dass ich nicht verwendet habe undef
, der auch die Überschreibung des Moduls auslöscht).
Also in einen Initialisierer geht der Code:
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
Wenn Sie die Reihenfolge des Ladens nicht kontrollieren können, können Sie die Methode in diesem Blog -Beitrag ausprobieren http://banisterfiend.wordpress.com/2010/11/04/baking-module-methods-into-classes-with-alias_method/
Ich habe es benutzt und es hat für mich funktioniert, aber das war mit Modulen, die ich selbst geschrieben hatte.
Ich habe ein Problem im i18N -Projekt eröffnet, um Slice sicherer zu machen, und eine PR erstellt, um es zu implementieren. Sie können das Problem / PR finden https://github.com/svenfuchs/i18n/pull/292.
Um sich manuell zu patchen, können Sie einfach hinzufügen if has_key?(key)
Nach dem Fetch.