- Rails 3.0.3
- Ruby 1.9.2
Próbując deserializowania bardzo prosty obiekt za pomocą YAML.load
lub Marshal.load
produkuje uszkodzony obiekt, ponieważ klasa, do której należy, nie jest wymagana w procesie deserializacji.Szyny nie ładuje zajęcia na deserializacji YAML/Marszałek obiekty
Przykład:
# 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
Z tego kodu możemy uruchomić tę sesję konsoli powłoki bez jakiegokolwiek błędu:
$ ruby -Itest test/unit/serializing_test.rb -n test_yaml_serialize_structure
$ ruby -Itest test/unit/serializing_test.rb -n test_yaml_deserialize_structure
Ale jeśli uruchomić deserializacji wzywa z Rails pocieszyć obiekt jest nie jest poprawnie deserializowany, ponieważ klasa nigdy nie jest wymagana:
$ 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"}>
wiem, jedynym problemem jest to, że klasa nie jest wymagane, ponieważ jeśli wymaga to ręcznie wszystko działa:
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">
Przedstawiłem tylko przykłady YAML ale z Marszałkiem jest całkiem to samo.
Mówię również, że chociaż odtwarzam problem w konsoli Railsowej pierwotnie ten problem doprowadzał mnie do szaleństwa w normalnym żądaniu do mojej aplikacji.
Pytanie brzmi: W jaki sposób można deserializować obiekty w Railsach bez konieczności ręcznego wykonywania wszystkich zajęć?
Dzięki
f.
Właśnie sobie sprawę, że to się stało tylko w środowisku programistycznym ** **. – fguillen
Widzę, że jeśli aktywuję 'config.cache_classes' deserialization działa dobrze, ale oczywiście: ** Przegrałem automatyczne odświeżanie klasy **:/ – fguillen