Simple ActiveRecord serialise problem

When I create a table with the following SQL:

create table foos (id SERIAL, content VARCHAR(255));

And define a class as follows:

class Foo < ActiveRecord::Base
serialize :content, JSON
end

Creating a new instance of the class gives an error:

f = Foo.new
NoMethodError: undefined method read' for nil:NilClass from /Users/andy/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.0/lib/active_support/whiny_nil.rb:48:inmethod_missing’
from
/Users/andy/Code/FakePlatform/vendor/gems/Darwin/gems/json-1.4.6/lib/json/common.rb:286:in
load' from /Users/andy/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.1.0/lib/active_record/base.rb:1938:inblock in set_serialized_attributes’

Does anyone have any ideas how to fix this?

It should work (it’s such a simple case).

Cheers,

Andy

On Oct 6, 11:02am, Andy J. [email protected] wrote:

When I create a table with the following SQL:

create table foos (id SERIAL, content VARCHAR(255));

And define a class as follows:

class Foo < ActiveRecord::Base
serialize :content, JSON
end

the second argument to serialise is used to say that you always want
the serialised object to be of a certain class (e.g. Hash, an
application specific class etc.). I’m not sure what you meant by
passing JSON as that argument but I suspect that it isn’t doing what
you think it is.

Fred

the second argument to serialise is used to say that you always want
the serialised object to be of a certain class (e.g. Hash, an
application specific class etc.). I’m not sure what you meant by
passing JSON as that argument but I suspect that it isn’t doing what
you think it is.
I was basing it on this article (as well as a stack overflow answer)
that you can provide a custom serializer in Rails 3.1:

JSON provides a dump and load method on the class so it should be
acceptable as the serializer.

Is this article incorrect or my understanding of it?

Cheers,

Andy

I was basing it on this article (as well as a stack overflow answer) that you
can provide a custom serializer in Rails 3.1:

JSON provides a dump and load method on the class so it should be acceptable as
the serializer.

Is this article incorrect or my understanding of it?
Having just had a read of ActiveRecord::Base, I still can’t see how I go
wrong

Base#serialize (line 557 of base.rb in ActiveRecord 3.1.0)

if the object supplied as the second argument responds to :load and
:dump (which JSON does), then it uses that object, if not it wraps it in
a YAMLColumn and sets the entry in serialized_attributes to that object.
Then in:

Base#arel_attributes_values (line 1963 of base.rb in ActiveRecord 3.1.0)

if there is an entry in serialized_attributes for a given attribute name
(with a value put in to the coder variable) it calls coder.dump with the
attribute value.

So, I can’t understand why JSON wouldn’t work as a second parameter…

Cheers,

Andy

I’ve also just tried upgrading JSON to 1.6.0 (as that’s the version that
seems to be installed if I do gem install json), same problem.

Cheers,

Andy

You’re using the syntax of serialize properly.

The problem looks like it’s in the JSON.load method not properly
handling a
nil value:

def load(source, proc = nil)
if source.respond_to? :to_str
source = source.to_str
elsif source.respond_to? :to_io
source = source.to_io.read
else
source = source.read
end
result = parse(source, :max_nesting => false, :allow_nan => true)
recurse_proc(result, &proc) if proc
result
end

Basically it gets to the line “source = source.read” and throws up
because
source is nil and nil doesn’t have a read method.