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 AM
I 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 PM
Can 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 AM
The issue here is that ActiveSupport defines
Object#to_json
, and thereforePost.where.to_json
tries 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 passes
This 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 AM
Requiring "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 PM
What 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) end
But 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 PM
I'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) } end
And this controller:
def index @listings = Listing.all @approved = Listing.approved ... end
This works:
respond_to do |format| format.json { render :json => @listings } end
Whereas using the named scope fails with a CircularReferenceError:
respond_to do |format| format.json { render :json => @approved } end
Note: this is in Rails3b3
-
Dan Sully June 22nd, 2010 @ 11:22 PM
This 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 PM
Attached 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 PM
How 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 @blackgold Could you please provide more information abou...
- 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
- 4547 ActiveSupport #to_json doesn't work with DM [#4547 state:resolved]