开发者

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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜