Skip to content

Error calling dup() on ActiveRecord model with serialized field #5797

gmcnaughton opened this Issue Apr 10, 2012 · 6 comments

4 participants


Starting with Rails >=3.2.2, I get the following error when calling dup() on a model with a serialized field:

# app/models/my_obj.rb
class MyObj < ActiveRecord::Base
  serialize :content, JSON
$ rails c
1.9.3-p0 :001 > => {"a" => "b"}).dup
TypeError: can't convert Hash into String
  from gems/json-1.6.6/lib/json/common.rb:148:in `initialize'
  from gems/json-1.6.6/lib/json/common.rb:148:in `new'
  from gems/json-1.6.6/lib/json/common.rb:148:in `parse'
  from gems/json-1.6.6/lib/json/common.rb:320:in `load'
  from gems/activerecord-3.2.3/lib/active_record/attribute_methods/serialization.rb:24:in `unserialize'
  from gems/activerecord-3.2.3/lib/active_record/attribute_methods/serialization.rb:15:in `unserialized_value'
  from gems/activerecord-3.2.3/lib/active_record/attribute_methods/read.rb:82:in `__temp__'
  from gems/activerecord-3.2.3/lib/active_record/attribute_methods/read.rb:46:in `type_cast_attribute'
  from gems/activerecord-3.2.3/lib/active_record/attribute_methods/read.rb:126:in `read_attribute'
  from gems/activerecord-3.2.3/lib/active_record/attribute_methods.rb:200:in `attribute_for_inspect'
  from gems/activerecord-3.2.3/lib/active_record/base.rb:643:in `block in inspect'
  from gems/activerecord-3.2.3/lib/active_record/base.rb:641:in `collect'
  from gems/activerecord-3.2.3/lib/active_record/base.rb:641:in `inspect'
  from gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start'
  from gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start'
  from gems/railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>'
  from script/rails:6:in `require'
  from script/rails:6:in `<main>'1.9.3-p0 :002

The above code works on Rails 3.2.1. It appears to be related to this commit for issue #4837.

The problem appears to be that after duping, the code tries to unserialize an already-unserialized value. The JSON parser chokes when it receives a Hash instead of a string.

kennyj commented Apr 10, 2012

I can reproduce this issue, and I fix it by the above commit (plan 1).

I guess we have new problem when merging my fix. Because I changed initialized_attributes method's signiture.

If we don't change it, I think the following code also fix it (plan 2).
What do you think ?

$ vim core.rb

def initialize_dup(other)
  cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
  serialized_attributes.each { |key, coder| cloned_attributes[key] = coder.dump(cloned_attributes[key]) } # ★added

cc/ @jonleighton


Thanks for the test case and the patch! Either solution sounds good to me, but I'll defer since I don't know the code :)

kennyj commented Apr 11, 2012

Thanks for your confirmation !
Anyway, I sent PR :-)

jrreed commented May 30, 2012


jtokash commented May 30, 2012


@kennyj kennyj closed this in d09b2fd May 30, 2012

Thanks guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.