ActiveRecord serialize的coder参数问题:关键字参数方式无法反序列化
问题解决:Rails serialize改用coder关键字参数后无法反序列化的问题
原来用serialize :charge, Charge能正常把数据库字符串转成Charge实例,但改成serialize :charge, coder: Charge后只返回字符串,核心问题是你的Charge类没有实现coder要求的self.load和self.dump方法。
Rails的serialize关键字参数模式下,指定的coder类必须提供两个类方法:
self.dump(charge):负责把Charge实例转换成可存储到数据库的字符串self.load(string):负责把数据库里的字符串还原成Charge实例
原来的位置参数写法,Rails会自动用YAML序列化逻辑帮你处理,但改用coder参数后,需要你明确实现这两个方法来接管序列化/反序列化流程。
举个具体的实现例子:
class Charge def initialize(amount, currency) @amount = amount @currency = currency end # 把Charge实例转成数据库可存储的字符串 def self.dump(charge) return nil unless charge.is_a?(Charge) [charge.amount, charge.currency].join(',') end # 把数据库里的字符串转成Charge实例 def self.load(string) return nil unless string.present? amount, currency = string.split(',') new(amount.to_i, currency) end attr_reader :amount, :currency end
然后在Entry类里保持serialize :charge, coder: Charge的写法,就能正常反序列化了。
如果想和原来位置参数的YAML序列化行为完全一致,也可以直接指定YAML编码器:
serialize :charge, coder: ActiveRecord::Coders::YAMLColumn.new(Charge)
这种写法不需要修改Charge类,效果和旧的位置参数完全相同,同时规避弃用警告。
内容的提问来源于stack exchange,提问作者Daniel Doherty
相关产品推荐
相关产品推荐

