This project is archived and is in readonly mode.

ActiveSupport #to_json doesn't work with DM
Reported by siplux | May 6th, 2010 @ 10:55 PM
object#to_json will fail with
"ActiveSupport::JSON::Encoding::CircularReferenceError: object
references itself"
This is due to the usage of "instance_values" in the #as_json
method. DM objects carry a _@repository ivar which carries a
reference to the original object.
This can be fixed by adding "dm-serializer" to the Gemfile, which implements its own #to_json method.
on line 137 of
activesupport/lib/active_support/json/encoding
  def as_json(options = nil)
if respond_to?(:to_hash)
  to_hash
else
  instance_values
end
end
The following will reproduce the issue
require 'dm-core'
require 'active_support'
require 'active_support/json'
class Foo
  include DataMapper::Resource
  property :id, Serial
  property :name, String
end
DataMapper.setup(:default, 'sqlite3::memory:')
DataMapper.auto_migrate!
Foo.create(:name => "foo").to_json
Comments and changes to this ticket
- 
            
         siplux May 8th, 2010 @ 11:46 PM- Tag changed from rails3 compatibility, datamapper, rails3 to rails3 compatibility, activesupport, datamapper, rails3
 
- 
         Dan Pickett May 9th, 2010 @ 06:36 PM- Tag changed from rails3 compatibility, activesupport, datamapper, rails3 to rails3 compatibility, activesupport, bugmash, datamapper, rails3
 
- 
            
         
- 
         Neeraj Singh May 11th, 2010 @ 02:44 PM@lawrence Can you provide an example where you are running into same problem with ActiveRecord. I am able to reproduce this error with DM. I guess if one of the instance variables refers back to the original object as is the case with the first example provided then I see two choices. 1) Let use pass an option :ignore_circular_reference => true. In this case in stead of raising an error, to_json method will ignore the circular reference and will move on. 2) Let user pass an option :ignore_items => _my_intance_variable. This will provide more control to user and rather than ignoring all circular references, user is asking to_json to ignore just this variable. 
- 
            
         blackgold9 May 12th, 2010 @ 06:03 AMI hit the same thing with my models. 
 In my case, it fails if i attempt to call to_json on an activerelation object (i.e. church.where().to_json), but works if i do church.where().to_a.to_jsonmy model is: class Church < ActiveRecord::Base 
 has_many :people has_many :groups validates_presence_of :name endThe only property it has is name. 
- 
         Santiago Pastorino May 12th, 2010 @ 03:25 PMCan someone provide a failing test using ActiveRecord? i've tried the thing that blackgold9 said but works for me ... 
 http://pastie.org/957044
- 
         Ryan Bigg May 13th, 2010 @ 11:56 PM- State changed from new to incomplete
 Please provide a test case and patch for this issue. 
- 
            
         Bernerd Schaefer May 25th, 2010 @ 12:35 AMThe issue here is that ActiveSupport defines Object#to_json, and thereforePost.where.to_jsontries to dump the ActiveRecord::Relation object instead of passing the method call on to it's internal collection. Note, this also applies toObject#to_yaml:# script/rails console include Test::Unit::Assertions relation = Post.where # or Post.where(:author_id => 1), etc. assert_nothing_raised(ActiveSupport::JSON::Encoding::CircularReferenceError) { relation.to_json } # fails assert_nothing_raised(TypeError) { relation.to_yaml } # fails ActiveRecord::Relation.send(:undef_method, :to_json) ActiveRecord::Relation.send(:undef_method, :to_yaml) assert_equal relation.to_a.to_json, relation.to_json # and now passes assert_equal relation.to_a.to_yaml, relation.to_yaml # and now passesThis is important because it causes the following code to generate a 500 when requesting /posts/mine.json:class PostsController < ApplicationController respond_to :html, :xml, :json def mine @posts = Posts.where(:author_id => 1) respond_with(@clients) end end
- 
            
         Marcin Kulik June 10th, 2010 @ 10:53 AMRequiring "json/pure" solves the problem for DataMapper, you just need to implement to_json for your models (or for DataMapper::Model). 
- 
            
         Lawrence Pit June 10th, 2010 @ 12:28 PMWhat Bernerd says.. exactly the issue I have. None of my controllers work when a json request is done. You'd think this workaround would work: def mine @posts = Posts.where(:author_id => 1).all respond_with(@posts) endBut that too fails in rails edge since a while, with "ArgumentError: wrong number of arguments (2 for 1)". Posts.where(:author_id => 1).to_yaml does work, Posts.where(:author_id => 1).to_json doesn't. I attempted to create a patch, but for some reason the delegation of to_json to to_a in ActiveRecord::Relation doesn't work. Anybody else have an idea? (see attached what I tried; I also tried what Bernerd did, undef_method of to_json, same result) 
- 
         Neeraj Singh June 10th, 2010 @ 04:07 PM- Tag changed from rails3 compatibility, activesupport, bugmash, datamapper, rails3 to rails3 compatibility, activesupport, bugmash, datamapper, patch, rails3
 Attached is a patch along with test which makes it possible to have code like User.where(:name => 'John').to_json
- 
         José Valim June 10th, 2010 @ 06:59 PMI'm not sure if we should allow Post.where(:omg).to_json. If so, what about to_xml? And to_yaml? 
- 
            
         Ola Tuvesson June 22nd, 2010 @ 02:20 AM- Tag changed from rails3 compatibility, activesupport, bugmash, datamapper, patch, rails3 to json to_json, rails3 compatibility, activesupport, bugmash, datamapper, patch, rails3
 I am having this same issue with a named scope. Given this model: class Listing < ActiveRecord::Base belongs_to :company scope :approved, lambda { where("approved = ?", true) } endAnd this controller: def index @listings = Listing.all @approved = Listing.approved ... endThis works: respond_to do |format| format.json { render :json => @listings } endWhereas using the named scope fails with a CircularReferenceError: respond_to do |format| format.json { render :json => @approved } endNote: this is in Rails3b3 
- 
            
         Dan Sully June 22nd, 2010 @ 11:22 PMThis is still an issue with DataMapper 1.0.0 and Rails3 beta4. The above work-arounds using json/pure or dm-serializers don't work for me. The test script by the original poster still fails. 
- 
         Neeraj Singh June 23rd, 2010 @ 03:09 PM- Assigned user set to José Valim
 Attached is patch with test. 
- 
         Neeraj Singh June 23rd, 2010 @ 04:56 PMAttached is patch with to_xml support. This patch needs be applied in addition to the patch previously mentioned. 
- 
         Repository June 23rd, 2010 @ 05:17 PM- State changed from incomplete to resolved
 (from [eb04408a20628a49296e0859425940b39a83ec63]) ActiveRecord's relation object should respond to to_json and to_yaml [#4547 state:resolved] Signed-off-by: José Valim jose.valim@gmail.com 
 http://github.com/rails/rails/commit/eb04408a20628a49296e0859425940...
- 
            
         Marcin Kulik June 23rd, 2010 @ 07:20 PMHow above ActiveRecord patch is supposed to solve serializing DataMapper objects?? 
- 
         José Valim June 23rd, 2010 @ 07:25 PM- State changed from resolved to open
 Hahahaha! The patch was not supposed to close this issue, it just solves another issue raise in this same thread. Reopening. 
- 
         José Valim June 26th, 2010 @ 10:49 AM- State changed from open to invalid
- Importance changed from  to Low
 About Datamapper: you need to define a as_json implementation for your models, otherwise Rails will use the default implementation causing the errors you mentioned. Maybe, dm-rails guys, could include a default as_json implementation. But I cannot see anything Rails could do here. 
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Attachments
Referenced by
- 
         4573 
          to_json on ActiveRecord::Relation throws CircularReference Exception 
        This is a duplicate of 
https://rails.lighthouseapp.com/p... 4573 
          to_json on ActiveRecord::Relation throws CircularReference Exception 
        This is a duplicate of 
https://rails.lighthouseapp.com/p...
- 
         4573 
          to_json on ActiveRecord::Relation throws CircularReference Exception 
        @blackgold Could you please provide more information abou... 4573 
          to_json on ActiveRecord::Relation throws CircularReference Exception 
        @blackgold Could you please provide more information abou...
- 
         4573 
          to_json on ActiveRecord::Relation throws CircularReference Exception 
        Duplicate of #4547. 4573 
          to_json on ActiveRecord::Relation throws CircularReference Exception 
        Duplicate of #4547.
- 
         4943 
          [PATCH] ActiveRecord live scope #to_json fix.  Prevents the CircularReferenceError error
        This is duplicate of #4547 4943 
          [PATCH] ActiveRecord live scope #to_json fix.  Prevents the CircularReferenceError error
        This is duplicate of #4547
- 
         4547 
          ActiveSupport #to_json doesn't work with DM
        [#4547 state:resolved] 4547 
          ActiveSupport #to_json doesn't work with DM
        [#4547 state:resolved]
 Jeremy Kemper
      Jeremy Kemper
 José Valim
      José Valim
 Marcin Kulik
      Marcin Kulik
 Ola Tuvesson
      Ola Tuvesson
 Ryan Bigg
      Ryan Bigg