1

I18n liest aus UTF-8 formatiert YML, und übersetzen wird von UTF-8 zu UTF-8 zu übersetzen.Codierungsprobleme in ActiveModel :: Fehler

Meine Legacy Codes stützt sich stark auf ActiveModel :: Errors.full_messages,

ZB

# note: the message is not utf-8 encoding 
validates_length_of :title,:maximum => 2,:message => 'abc'.encode("shift_jis") 

In Anbetracht, verwendet es:

item.errors.full_messages.each do |msg| 
end 

Der Fehler so etwas wie sein:

I18n.t(:title) + " " + 'abc' 

In der Tat, in full_message Funktion, die reale Quellcode so etwas wie ist:

def full_message(attribute, message) 
    return message if attribute == :base 
    attr_name = attribute.to_s.tr('.', '_').humanize 
    attr_name = @base.class.human_attribute_name(attribute, default: attr_name) 
    I18n.t(:"errors.format", { 
    default: "%{attribute} %{message}", 
    attribute: attr_name, 
    message: message 
    }) 
end 

Das Problem ist jetzt: die% {attribute} ist utf-8 und die% {Nachricht} ist nicht utf-8, Daher wird beim Aufruf von full_message ein Fehler angezeigt.

Es gibt mehrere Lösungen, die ich mir vorstellen kann:

1) ändern Fehlermeldungen utf-8 (es gibt eine Menge von anderen Saiten, die nicht utf-8) sind, so dass ich mit dem beschäftigen Kombination von utf-8 und non-utf-8 überall in den Quellcodes und richtige Konvertierung, wenn sie zusammenkommen.

2) einen Weg finden, Fehlermeldungen aufzulisten (ähnlich wie full_messages), aber mit einer anderen Implementierung. Ich habe versucht, in die API von ActiveModel :: errors zu schauen, und konnte die interne API nicht finden, so dass ich Fehler aufzählen kann.

3) ändern Sie das Standardverhalten von I18n.t, so dass es nicht-utf-8 zurückgibt.

4) Ändern Sie ActiveModel :: Errors.full_messages, so dass es nicht-UTF-8 zurückgibt.

Die zweite Option ist eigentlich die beste Option, aber ich bin mir nicht sicher, wie die Fehlermeldungen auf die gleiche Weise wie full_messages aufgezählt werden. Ich konnte keine öffentliche API finden, um die interne Datenstruktur von Fehlern zurückzugeben?

Die letzten 2 Optionen erfordern Injektion in Ruby-Bibliothek, die ich nicht weiß, ob es möglich ist oder nicht.

Bitte zeigen Sie mir einige Hinweise. Vielen Dank.

Antwort

1

Sie können das Verhalten von fast allem in Ruby (und Schienen) ändern.

Erstellen Sie einfach eine neue initialiser Datei in config/initializers mit so etwas wie:

#monkeypatch_i18n.rb 
(i don't know the exact path of active_model/errors.full_messages) 
module ActiveModel 
    module Errors 
    def full_messages 
     #new logic 
    end 
    end 
end 

dies überschreibt die Standard-Methode.

grüße, juanma.

edit: Eine saubere Lösung könnte sein:

#lib/monkey_patch_i18n.rb 
module ActiveModel 
     module Errors 
     def full_messages 
      #new logic 
     end 
     end 
    end 

#config/initializers/init_i18n.rb 
require "#{Rails.root}/lib/monkey_patch_i18n.rb"