我的目标是将一组对象序列化为一个文件,以便创建一个备份。我开始工作,使用模型上的方法(这里简化,假设我有两个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方法可以自动完成。不幸的是,在这种情况下,谷歌不是我的朋友。我只能看到在Web请求中关注json的页面,但不会以这种方式解析json。有什么我缺少的,或者我应该编写代码直接拆分字符串并读取对象类型?
如果我写代码直接拆分字符串,我会写下以下内容:
objectType = line[/^{"(\w*)"=>(.*)}/, 1]
objectHash = line[/{"(\w*)"=>(.*)}/, 2]
这非常难看,我确信有一种更好的方法(我仍在研究),但我不确定这是否是正确的方法v有自动查看json表示的东西并从根值知道要实例化的对象。
最后,使用from_json的实际实例化也不起作用,它不会填充ActiveRecord上的任何字段。它给了我nil参数,所以我认为解析语法不正确。
所以,这提出了三个问题:
(注意:随着时间的推移编辑以澄清我的问题,因为我现在有一个正常的正则表达式(之前没有),但仍然不确定它是否非常优雅。)
进一步的信息 - 这里的一个问题,正如我进一步深入研究的那样,as_json实际上并没有给我json - 我在文件中的内容是哈希,而不是json。此外,散列中的created_at和lastupdated_at的值不会被引用 - 所以基本上这就是导致解析失败的原因。我已经知道我应该使用to_json而不是as_json,尽管文档表明as_json应该可以工作。
答案 0 :(得分:0)
我不确定我是否完全理解你的方法论,但我认为使用JSON.parse()
会有所帮助。
这里有一些很好的信息http://mike.bailey.net.au/2011/02/json-with-ruby-and-rails/
这可以帮助您将原始对象转换回哈希值。
答案 1 :(得分:0)
好的,所以我觉得我有一些有用的东西。我完全不相信它优雅,但它给了我结果。我会花一些时间试图让它更清洁。
代码如下所示:
file.each_line do |line|
objectType = line[/^{"(\w*)":(.*)}/, 1]
objectJSON = line[/{"(\w*)":(.*)}/, 2]
objectHash = JSON.parse(objectJSON)
case objectType
when 'foo'
restoredFoo = Foo.new(objectHash.except('id', 'created_at', 'updated_at'))
restoredFoo.created_at = objectHash['created_at']
restoredFoo.updated_at = objectHash['updated_at']
restoredFoo.save!
end
when 'bar'
restoredBar = Bar.new(objectHash.except('id', 'created_at', 'updated_at'))
restoredBar.created_at = objectHash['created_at']
restoredBar.updated_at = objectHash['updated_at']
restoredBar.save!
end
end
注意事项:
但是说了这么多,它确实有效,这是一个很好的一步。