【发布时间】:2010-09-07 18:09:14
【问题描述】:
您好!
在 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
此方法引用编码器类。就是这样:
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 文档非常有限,并且没有实现示例。
任何帮助表示赞赏,在此先感谢!
编辑:
解决办法如下:
好的,所以问题似乎比最初出现的更微妙。经过额外的测试,我发现事实上,正如 Jeppe 指出的那样,无论弃用警告如何,after_find 回调都在工作,“to_utf8”方法实际上已成功调用并在模型属性上执行。结果与预期不符的原因是“to_utf8”方法本身。它的作用是使用 ruby 模块 Iconv 将字符串从非 utf8 编码(例如 cp1251)转换为 utf。这是针对使用 Active Record 从具有非 utf 编码的远程旧数据库中获取的模型的属性完成的。然而,事实证明,与以前版本的 rails 不同,rails 3 中的 AR 自动并静默处理所有对象到 ut8 的转换,即使是从非 unicode 的数据库中获取的对象。所以基本上在升级之后,我的代码最终重新转换为 utf8 字符串,这些字符串已经被 AR 转换为 utf8,结果是一堆乱码。该问题已通过完全删除 after_find 和 after_save 回调得到解决,因为在这种情况下不再需要它们:)
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3