Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #8933 (reopened defect)

Opened 1 year ago

Last modified 7 months ago

Deserializing object failed in ActiveRecord

Reported by: omnibus Assigned to: core
Priority: high Milestone: 2.x
Component: ActiveRecord Version: 1.2.3
Severity: major Keywords: serialize deserialize
Cc:

Description

When I migrate codes from 1.1.2 to 1.2.3, the serialize in ActiveRecord failed to deserialize object correctly.

Relevant model classes of ListTracker, QueryList and Query

class ListTracker < ActiveRecord::Base
  serialize :query_list
  serialize :query
  belongs_to :user
end
class QueryList
  attr_accessor :class_name
  def initialize(class_name = "")
    @items = []
    @restrict_items = []
    @class_name = class_name.strip
    @order_field = "id"
    @order_direction = ""
    @sort_items = []
    @table_included = Set.new
  end

  def class_name
    @class_name ||= ""
  end
  ......
end
class Query
  attr_accessor :key, :value, :exact, :op, :join, :negation, :table, :before_blanket_count, :after_blanket_count

  def initialize(key, value, table, op = "eq", join = "AND", negation = false, before_blanket_count = 0, after_blanket_count = 0)
    @key = "#{key}".strip
    value = "1" if value == true
    value = "0" if value == false
    @value = "#{value.to_s}".strip
    case op
    when true
      @op = "eq"
    when false
      @op = "st"
    when "eq", "ne", "lt", "gt", "le", "ge", "bl", "in", "st", "en"
      @op = op
    else
      @op = "eq"
    end
    @join = "#{join}".strip
    @negation = negation
    @table = table.strip || ""
    @before_blanket_count = before_blanket_count.to_i
    @after_blanket_count = after_blanket_count.to_i
  end
  ......
end

In 1.1.2, the behaviour is

>> t = ListTracker.find(:first)
=> #<ListTracker:0x40832058 @attributes={"updated_at"=>"2007-05-14 12:07:06", "module"=>"contacts", "query_list"=>"--- !ruby/object:QueryList \nclass_name: Contact\nitems: \n  - !ruby/object:Query \n    after_blanket_count: 0\n    before_blanket_count: 0\n    join: AND\n    key: id\n    negation: false\n    op: eq\n    table: contacts\n    value: 8543be1e-01d0-11dc-b78c-001372588291\norder_direction: ''\norder_field: id\nrestrict_items: []\nsort_items: []\ntable_included: !ruby/object:Set \n  hash: {}", "id"=>"64", "user_id"=>"f7163ddc-fc4a-11da-81a0-000c6e8c7636", "order_by"=>""}>
>> t.query_list
=> #<QueryList:0x40826e38 @restrict_items=[], @class_name="Contact", @sort_items=[], @order_direction="", @order_field="id", @table_included=#<Set: {}>, @items=[#<Query:0x4082dd14 @negation=false, @op="eq", @join="AND", @table="contacts", @after_blanket_count=0, @before_blanket_count=0, @value="8543be1e-01d0-11dc-b78c-001372588291", @key="id">]>

It will load the QueryList object.

In 1.2.3,

>> t = ListTracker.find(:first)
=> #<ListTracker:0xb6df9ca4 @attributes={"module"=>"contacts", "updated_at"=>"2007-04-04 16:13:17", "query_list"=>"--- !ruby/object:QueryList \nclass_name: Contact\nitems: \n  - !ruby/object:Query \n    after_blanket_count: 0\n    before_blanket_count: 0\n    join: OR\n    key: id\n    negation: false\n    op: st\n    table: contacts\n    value: 62d703da-707c-11db-80be-000c6e8c7636\n  - !ruby/object:Query \n    after_blanket_count: 0\n    before_blanket_count: 0\n    join: OR\n    key: id\n    negation: false\n    op: st\n    table: contacts\n    value: 1faad762-707c-11db-80be-000c6e8c7636\norder_direction: ''\norder_field: id\nrestrict_items: []\nsort_items: \n  - !ruby/object:QuerySort \n    descending: false\n    field: created_at\n    field_type: contacts\n    summary: false\ntable_included: !ruby/object:Set \n  hash: {}", "id"=>"64", "order_by"=>"", "user_id"=>"f7163ddc-fc4a-11da-81a0-000c6e8c7636"}>
>> t.query_list
=> #<YAML::Object:0xb6df355c @ivars={"items"=>[#<YAML::Object:0xb6df4358 @ivars={"op"=>"st", "after_blanket_count"=>0, "value"=>"62d703da-707c-11db-80be-000c6e8c7636", "table"=>"contacts", "before_blanket_count"=>0, "negation"=>false, "key"=>"id", "join"=>"OR"}, @class="Query">, #<YAML::Object:0xb6df3ebc @ivars={"op"=>"st", "after_blanket_count"=>0, "value"=>"1faad762-707c-11db-80be-000c6e8c7636", "table"=>"contacts", "before_blanket_count"=>0, "negation"=>false, "key"=>"id", "join"=>"OR"}, @class="Query">], "class_name"=>"Contact", "table_included"=>#<Set: {}>, "restrict_items"=>[], "order_direction"=>"", "sort_items"=>[#<YAML::Object:0xb6df3a5c @ivars={"field"=>"created_at", "summary"=>false, "descending"=>false, "field_type"=>"contacts"}, @class="QuerySort">], "order_field"=>"id"}, @class="QueryList">

Deserializing it gives a strange class of YAML::Object.

Hopefully there would be a fix so that it can deserialize like 1.1.2.

Change History

11/20/07 20:23:48 changed by ivarv

Just a note to add that this is still broken in 1.2.5

11/20/07 23:21:44 changed by ivarv

  • status changed from new to closed.
  • resolution set to duplicate.

duplicate of 8855

11/21/07 12:44:46 changed by candlerb

  • status changed from closed to reopened.
  • resolution deleted.

8855 is for an issue with ActiveResource, this ticket is for ActiveRecord.

12/10/07 11:20:30 changed by sunfmin

For some quick dirty fix Load the QueryList.. class before deserialize happens

I think rails dependency system didn't load the class before deserialize cause the problem.

change the ListTracker to:

class ListTracker < ActiveRecord::Base
  QueryList
  Query

  serialize :query_list
  serialize :query
  belongs_to :user
end

hope this helps.