Grettings!
В приложении, которое работало безупречно в Rails 2.3.8, у меня есть следующий метод класса:
def self.encode(*attr_names)
encoder = Encoder.new(attr_names)
before_save encoder
after_save encoder
after_find encoder
define_method(:after_find) { } # defining here, since there's only alias in the Encoder class itself
end
Этот метод ссылается на класс Encoder. Вот оно:
class Encoder
include Encodings
def initialize(attrs_to_manage) # We're passed a list of attributes that should be stored encoded in the database
@attrs_to_manage = attrs_to_manage
end
def before_save(model) # Before saving or updating, encode the attributes to their original encoding
@attrs_to_manage.each do |field|
model[field] = to_orig_encod(model[field])
end
end
def after_save(model) # After saving, encode them back to utf8
@attrs_to_manage.each do |field|
model[field] = to_utf8(model[field])
end
end
alias_method :after_find, :after_save # Do the same after finding an existing record
end
До обновления до rails3 все обратные вызовы (before_save, after_save, after_find) работали нормально. После обновления before_save и after_save все еще работают, но after_find не работает, и в моем журнале появляется следующее предупреждение об устаревании:
DEPRECATION WARNING: Base#after_find has been deprecated, please use Base.after_find :method instead
Я не уверен, как изменить свой код, чтобы снова включить функциональность обратного вызова after_find. Я попробовал несколько простых изменений безуспешно, и документация по rails API для этого обратного вызова очень ограничена и без примеров реализации.
Любая помощь приветствуется, спасибо заранее!
Edit:
Вот решение:
Хорошо, похоже, проблема была более тонкой, чем изначально показалась. После дополнительного тестирования я обнаружил, что на самом деле, как указал Jeppe, обратный вызов after_find работает независимо от предупреждения об устаревании, метод to_utf8 фактически был успешно вызван и выполнен для атрибутов модели. Причиной того, что результат не соответствовал ожиданиям, был сам метод to_utf8. Он использует модуль ruv Iconv для преобразования строк из кодировки не-utf8, например, cp1251, например, в utf. Это было сделано для атрибутов модели, выбранной с помощью Active Record из удаленной устаревшей базы данных с кодировкой не-utf. Однако, как оказалось, в отличие от предыдущих версий рельсов, AR в рельсах 3 автоматически и автоматически выполняет преобразование в ut8 всех объектов, даже тех, которые извлечены из баз данных, которые не являются Unicode. Таким образом, по сути, после обновления мой код в конечном итоге преобразовал в строки utf8, которые уже были преобразованы AR в utf8, и в результате получился беспорядочный набор символов. Проблема была решена путем полного удаления обратных вызовов after_find и after_save, так как в этом случае они больше не нужны:)