- 导轨:3.0.3
- 红宝石:1.9.2
尝试使用反序列化非常简单的对象YAML.load
或Marshal.load
产生损坏的对象,因为反序列化过程不需要所属的类。
例子:
# app/models/my_model.rb
class MyModel
attr_accessor :id
end
# test/unit/serializing_test.rb
require 'test_helper'
class SerializingTest < Test::Unit::TestCase
def test_yaml_serialize_structure
my_model = MyModel.new
my_model.id = 'my model'
File.open( "#{Rails.root}/tmp/object.yml" , 'w' ) do |f|
YAML::dump(my_model, f)
end
end
def test_yaml_deserialize_structure
object = YAML.load_file "#{Rails.root}/tmp/object.yml"
assert( object.instance_of? MyModel )
assert_equal( 'my model', object.id )
end
end
使用此代码,我们可以运行此 shell 控制台会话而不会出现任何错误:
$ ruby -Itest test/unit/serializing_test.rb -n test_yaml_serialize_structure
$ ruby -Itest test/unit/serializing_test.rb -n test_yaml_deserialize_structure
但是,如果我从 Rails 控制台运行反序列化调用,则对象不会正确反序列化,因为永远不需要该类:
$ rails c
ruby-1.9.2-p0 > object = YAML.load_file "#{Rails.root}/tmp/object.yml"
=> #<Syck::Object:0x0000010322ea30 @class="MyModel", @ivars={"id"=>"my model"}>
我知道唯一的问题是不需要该课程,因为如果我手动需要它,一切正常:
ruby-1.9.2-p0 > require "#{Rails.root}/app/models/my_model"
=> ["MyModel"]
ruby-1.9.2-p0 > object = YAML.load_file "#{Rails.root}/tmp/object.yml"
=> #<MyModel:0x0000010320c8e0 @id="my model">
我只介绍了 YAML 示例,但与 Marshal 几乎相同。
还要说,虽然我最初在Rails 控制台中重现了这个问题,但这个问题让我在对我的应用程序的正常请求中变得疯狂。
所以问题是:如何在 Rails 中反序列化对象而不必手动要求所有类?
谢谢
F。