Re: unable to use json

I got the same error when trying something like this:

people = Person.find(:all)people.to_json

So people is an array of Person objects. The problem is, the Person object, which is a subclass of ActiveRecord::Base, has a to_json method that allows only one argument. Array.to_json, which comes from json_pure, tries to call a to_json method on each of the Array's elements, but it tries to pass in two arguments, state and depth - both of which the ActiveRecord to_json doesn't use.

I don't know if this is your situation, but the solution for me was to override the to_json method in my Person class. This allows the to_json method to be called with two arguments, but passes neither of them along to the super (which is the original to_json):

Re: unable to use json

We are having the same problem. We are using rails 2.1.0 and we have installed the json gem in order to use from_json outside of ActiveRecord. Unfortunately, this function is not included in Rails. As a result, my coworkers are having the exact same error as described in this thread, in certain cases when to_json is called. We do not experience this on our OS X machines, but do on our Windows machines. The difference is that the OS X machines use the C version of the JSON gem and the windows machines use JSON pure. Any help in figuring this out would be great. Or perhaps a way to use the JSON gem only for from_json and always use the rails version for to_json. BTW, our require state is require 'json/add/rails'and always has been.

Re: unable to use json

Hi, I'm suffering from the exact same problem, and I just wanted to share what I've found out so far, in case someone knows better.

It seems that json gem has defined to_json(*) method which takes multiple arguments, and is using that to call in structured objects like Array or Hash. Now, it tried to define for lots of Objects, like Time, DateTime, Date stuff, but what Rails(2.1.0) is actually using is ActiveSupport::TimeWithZone, which is NOT defined.

so, when you call Person.first.to_json, which probably has a created_at, it tries to call TimeWithZone.to_json(nil, 1). Since TimeWithZone is not defined in json gem, it goes to ActiveRecord implementation, but there only to_json(arg) is defined. It cannot accept to_json with two arguments, so it raises an ArgumentError.

What I thought was, is that since require method is ignored after it has been called once, it won't be a problem when I call it later again, in some different Controller or something. So I required json in environment.rb, before the Initializer ran.

Having done only this, it actually worked, not emitting the ArgumentError exception. But surprisingly, if I require 'json' (or even 'json/add/rails') after the ActiveRecord was required, it makes that ArgumentError again. I don't know why this happens. I thought it would be OK to require afterwards, since I've done it once already.

Re: unable to use json

The problem is that the JSON gem blows. Doesn't work well on Windows, it's slow, incomplete, and buggy. "gem remove json" to be sure you never use accidentally use it. Now, if you eradicate all "require 'json'" lines from your Rails app, you'll never see this problem again.

How do you decode/encode JSON without the gem? Call ActiveSupport::JSON.decode(string) to decode and obj.to_json to encode.

If you want to do this in a script outside of Rails, you can just copy-n-paste Rails's code. So, to decode, paste the following to the top of your file (itself copy-n-pasted from vendor/rails/activesupport/lib/active_support/json/decoding.rb):

# copy-n-paste ActiveSupport's JSON code so this script will work anywhererequire 'yaml'require 'strscan'

# Ensure that ":" and "," are always followed by a space def convert_json_to_yaml(json) #:nodoc: scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, [] while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/) case char = scanner[1] when '"', "'" if !quoting quoting = char pos = scanner.pos elsif quoting == char if json[pos..scanner.pos-2] =~ DATE_REGEX # found a date, track the exact positions of the quotes so we can remove them later. # oh, and increment them for each current mark, each one is an extra padded space that bumps # the position in the final YAML output total_marks = marks.size times << pos+total_marks << scanner.pos+total_marks end quoting = false end when ":","," marks << scanner.pos - 1 unless quoting end end

Re: unable to use json

I had a similar problem. I am using ActiveRecord in a Sinatra app. One of the needed gems requires the json gem and is loaded before activerecord. I was trying to output json for a two element hash object, status => string and data => hash. Inside the data hash were a number of string elements, a number of floats and an array of strings. The to_json method raised TypeError: wrong argument type Hash (expected JSON::Ext::Generator::State) in gems/activesupport-2.2.2/lib/active_support/json/encoding.rb:21:in 'to_json'.

What transpires (as lizardwalker above points out) is that when encoding reached the array, the method being called was the array to_json from the json gem and not the enumerable to_json from activesupport. The parameters passed into the to_json methods by activesupport is an options hash whereas the json gem to_hash method is expecting a State and int - hence the exception.

My solution was to create a small ArrayAsEnumerable class that mixed in the Enumerable module and provided an each method. I stored a new instance of this class in place of the array and passed the array in as a parameter. Now the activesupport enumerable.to_json IS being called. This allows me to use the options hash to specify exclude, only and methods.

Incidentally moving the activerecord require to before the gem that loads json does not make any difference.