我的目标是将一组对象序列化到一个文件中以创建备份。我已经开始使用模型上的方法(在这里简化,假设我有两个 ActiveRecords foo 和 bar):
def backup(file, foo, bar)
file.write(foo.to_json(root: true))
file.write(bar.to_json(root: true))
end
这给了我一个我想要的文件,在这种情况下有两个记录:
{"foo":{"Account_id":1,"Name":"F","created_at":"2013-04-16T10:06:19Z","id":1,"updated_at":"2013-04-20T11:36:23Z"}}
{"bar":{"Account_id":1,"Name":"B","created_at":"2013-04-16T10:06:19Z","id":1,"updated_at":"2013-04-20T11:36:23Z"}}
稍后我想读取该备份并重新实例化这些对象,然后可能将它们持久化回数据库。我的目标是遍历文件检查每个对象的类型,然后实例化正确的对象。
我有部分逻辑,但还不是全部,我还没有弄清楚在实例化每个序列化对象之前如何确定它的类型。我的恢复代码如下:
def restore(file)
file.each_line do |line|
**<some magic that parses my line into objectType and objectHash>**
case objectType
when :foo
Foo.new.from_json(objectHash)
Foo.process
Foo.save!
when :bar
Bar.new.from_json(objectHash)
Bar.process
Bar.save!
end
end
end
我正在寻找的是“一些魔术”部分中的内容。我可以编写代码来直接解析该行以确定它是 foo 还是 bar,但我觉得可能有一些棘手的 Rails/Ruby 方法可以自动执行此操作。不幸的是,在这种情况下,谷歌不是我的朋友。我所能看到的只是网页请求中专注于 json 的页面,但没有以这种方式解析 json。有什么我遗漏的,还是我应该编写代码直接拆分字符串并读取对象类型?
如果我确实编写代码来直接拆分字符串,我会写一些类似的东西:
objectType = line[/^{"(\w*)"=>(.*)}/, 1]
objectHash = line[/{"(\w*)"=>(.*)}/, 2]
这很丑陋,我确信有更好的方法(我仍在研究),但我不确定这甚至是正确的方法 v 有一些东西可以自动查看 json 表示并从根值要实例化什么对象。
最后,使用 from_json 的实际实例化也不起作用,它没有填充我的 ActiveRecord 上的任何字段。它给了我 nil 参数,所以我认为解析语法不正确。
所以,这提出了三个问题:
- 有没有办法确定我刚刚丢失的对象是哪个,更干净?
- 如果没有并且我需要使用正则表达式,是否有一种语法可以一次性解析行的两个位,而不是我的两行具有相同的正则表达式?
- from_json 语法看起来不太好。我在这里缺少语法吗?(不再是一个问题 - 上面的代码是固定的,当它应该是 to_json 时我使用的是 as_json,尽管文档对此相当不清楚......)
(注意:随着时间的推移进行编辑以澄清我的问题,并且因为我现在有一个有效的正则表达式(以前没有),但仍然不确定它是否非常优雅。)
更多信息——这里的问题之一,当我进一步深入研究时,as_json 实际上并没有给我 json——我在文件中拥有的是一个哈希,根本不是 json。此外,散列中 created_at 和 lastupdated_at 的值没有被引用 - 所以基本上这就是导致解析失败的原因。我已经确定我应该使用 to_json 而不是 as_json,尽管文档表明 as_json 应该可以工作。