反序列化数据库对象

时间:2011-07-18 11:08:54

标签: ruby-on-rails ruby-on-rails-3

我有一个统计模型

class Statistic < ActiveRecord::Base
  serialize  :value
end

模型包含一个包含Goals对象的value属性。我想反序列化目标对象

当我做的时候

goals = Statistic.all
goals.each do |goal|
  test = goal.value      
end

我收到错误

value was supposed to be a Goals, but was a String

在调试器中,我看到goal.value的类型为String,包含目标数据

--- !ruby/object:Goals \ngoals: {}\n\ngoals_against: 1\ngoals_for: 0\nversion: 1\n

当我添加serialize :value, Goals时,我在反序列化时会出现以下错误

ActiveRecord::SerializationTypeMismatch in ClubsController#new

value was supposed to be a Goals, but was a String

目标课程

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

有人知道我怎么能让铁杆知道它是一个目标对象而不是一个字符串?

由于

1 个答案:

答案 0 :(得分:2)

我对序列化问题的大多数经验来自Rails 1时代,但我记得序列化失败的两个常见原因:

  • 默默忽略异常
  • 课程重装

查看文件./activerecord/lib/active_record/base.rb(来自git的标签v3.0.7)我看到有一个'rescue'条款:

def object_from_yaml(string)
  return string unless string.is_a?(String) && string =~ /^---/
  YAML::load(string) rescue string
end

您可以尝试调查YAML::load引发的异常。我通常会将此方法更改为以下内容:

  begin
    YAML::load(string)
  rescue => e
    Rails.logger.warn "YAML exception (ignored): #{e.inspect}"
    string
  end

关于班级重装,你的问题在测试模式下也可见吗?我在YAML中注册我的类,并注意到每个第二个请求中的类定义都消失了,因为重新创建了类对象,并且已经注册的类被从类链中删除。我不认为这是你的问题,但无论如何我都在发出信号 - 也许这会有所帮助?