#1360 ✓resolved
Jason LaPorte

to_json in dm-serializers throws exceptions on included associations.

Reported by Jason LaPorte | July 14th, 2010 @ 08:18 AM

Hello,

I have been starting to experiment with DataMapper and have thus far been pretty pleased; unfortunately, I recently ran into a bug that is preventing me from continuing to use it in projects. When including dm-serializers and calling the "to_json" method on anything with included associations (via :methods), I get an exception thrown. (I will note that to_xml seems to work flawlessly.)

I have created the following illustrative use-case:

require 'rubygems'
require 'dm-core'
require 'dm-migrations'
require 'dm-serializer'

DataMapper.setup(:default, 'sqlite://:memory:')

class A
  include DataMapper::Resource
  property :id, Serial
  has n, :bs
end

class B
  include DataMapper::Resource
  property :id, Serial
  belongs_to :a
end

DataMapper.finalize
DataMapper.auto_migrate!

# Works fine, printing '[]'.
puts A.all.to_json(:methods => [:bs])

A.create

# Also works fine, printing '[{"id":1}]'.
puts A.all.to_json

# However, this one does not and throws an exception.
puts A.all.to_json(:methods => [:bs])

The output of executing this is as follows:

$ ruby -v
ruby 1.8.7 (2010-06-23 patchlevel 299) [x86_64-linux]
$ gem list
...
dm-core (1.0.0)
dm-migrations (1.0.0)
dm-serializer (1.0.0)
dm-sqlite-adapter (1.0.0)
...
$ ruby testcase.rb 
[]
[{"id":1}]
/usr/local/lib/ruby/gems/1.8/gems/dm-serializer-1.0.0/lib/dm-serializer/to_json.rb:76:in `to_json': undefined method `merge' for #<JSON::Ext::Generator::State:0x7fa00f0c7298> (NoMethodError)
    from /usr/local/lib/ruby/gems/1.8/gems/dm-serializer-1.0.0/lib/dm-serializer/to_json.rb:81:in `to_json'
    from testcase.rb:32

I would also note that using :methods is not well documented. The only place I found reference to it was on http://github.com/datamapper/dm-more/tree/master/dm-serializer#readme, in one little sentence under "How it works". Since I would imagine that serializing an object with associations to be a common use case (it certainly was in my case, building a JSON API with Sinatra and DataMapper), it would probably be wise to document this in more detail.

Comments and changes to this ticket

  • Alex

    Alex August 19th, 2010 @ 01:22 PM

    I'm experiencing the same issue when using the :methods configuration of to_json. Also found a :relationships configuration option, but this appears to not use datamapper's lazy-loading optimizations.

    The following will create a query for each instance of A.

    A.all.to_json(:relationships=>{:bs=>{}})
    

    What's the best way to include associated models when calling to_json?

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) September 17th, 2010 @ 10:56 PM

    • State changed from “new” to “resolved”

    (from [817b8ddd7d3f60f44b8aaf662b8dd78f289df567]) Fixed problem with JSON::Ext::Generator::State passed in for #to_json options

    • The old code assumed that the object passed in was either nil or a Hash, or something that can be coerced into a Hash. However, in certain cases, such as when JSON itself is handling serialization, it will pass in a JSON::Ext::Generator::State object. This fix will ignore anything other than a Hash passed in.

    [#1412 state:resolved] [#1360 state:resolved] http://github.com/datamapper/dm-serializer/commit/817b8ddd7d3f60f44...

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

People watching this ticket

Referenced by

Pages