deserialize database object
I have a statistic model
class Statistic < ActiveRecord::Base
serialize :value
end
The model contains a value attribute containing a Goals object. I want to deserialize the goals object
when I d开发者_高级运维o
goals = Statistic.all
goals.each do |goal|
test = goal.value
end
I get an error
value was supposed to be a Goals, but was a String
In the debugger I see that goal.value is of type String and contains the goal data
--- !ruby/object:Goals \ngoals: {}\n\ngoals_against: 1\ngoals_for: 0\nversion: 1\n
When I add serialize :value, Goals
I get following error when deserialzing
ActiveRecord::SerializationTypeMismatch in ClubsController#new
value was supposed to be a Goals, but was a String
The Goals class
class Goals
attr_accessor :goals
attr_accessor :goals_for
attr_accessor :goals_against
attr_accessor :goals_own
attr_accessor :penalty_for
attr_accessor :penalty_against
def initialize(goals = nil, goals_against = nil, goals_own = nil, penalty_for = nil, penalty_against = nil)
@version = 1
if goals.nil?
@goals = {}
else
@goals = goals
end
@goals_against = goals_against.to_i
@goals_own = goals_own.to_i unless goals_own.nil?
unless penalty_for.nil?
@penalty_for = penalty_for.to_i
@penalty_against = penalty_against.to_i
end
set_goals_for()
end
private
def set_goals_for
@goals_for = 0
@goals.each_value {|value| @goals_for += value.to_i }
@goals_for += @goals_own unless @goals_own.nil?
end
end
Someone knows how I can make rails know that its an goals object and not a string?
Thanks
Most of my experience with serialization problems comes from Rails 1 era, but I recall two usual reasons of serialization failures:
- silently ignored exceptions
- class reloading
Looking at the file ./activerecord/lib/active_record/base.rb
(tag v3.0.7 from git) I see that there is a 'rescue' clause:
def object_from_yaml(string)
return string unless string.is_a?(String) && string =~ /^---/
YAML::load(string) rescue string
end
You may try to investigate what exception is thrown by YAML::load
. I usually change this method into something like this:
begin
YAML::load(string)
rescue => e
Rails.logger.warn "YAML exception (ignored): #{e.inspect}"
string
end
About the class reloading, is your problem also visible in test mode? I was registering my classes in YAML, and noticed that the class definition was gone in each second request, since the class object was recreated, and the registered one was taken away from the class chains. I don't think this is your problem, but I am signalling it anyway - maybe this will be helpful?
精彩评论