This project is archived and is in readonly mode.
ActiveSupport::JSON.encode fails for Struct types
-
iain
- Tag changed from json to_json encode struct to as_json, encode_json, json, to_json
+1
It's not really a problem with Structs, but with classes included in native structures.
A test case:
class Sub def as_json(*) { :foo => "bar" } end end class Base def as_json(*) [ Sub.new ] end end puts Base.new.to_jsonResulting in the error reported:
[GEM_HOME]/activesupport-3.0.3/lib/active_support/json/encoding.rb:214:in `encode_json': undefined method `encode_json' for #<Sub:0x102a02a78> (NoMethodError) from [GEM_HOME]/activesupport-3.0.3/lib/active_support/json/encoding.rb:214:in `map' from [GEM_HOME]/activesupport-3.0.3/lib/active_support/json/encoding.rb:214:in `encode_json' from [GEM_HOME]/activesupport-3.0.3/lib/active_support/json/encoding.rb:47:in `encode' from [GEM_HOME]/activesupport-3.0.3/lib/active_support/json/encoding.rb:77:in `check_for_circular_references' from [GEM_HOME]/activesupport-3.0.3/lib/active_support/json/encoding.rb:45:in `encode' from [GEM_HOME]/activesupport-3.0.3/lib/active_support/json/encoding.rb:30:in `encode' from [GEM_HOME]/activesupport-3.0.3/lib/active_support/core_ext/object/to_json.rb:15:in `to_json' from json_test.rb:15 -
iain
BTW: this issue was introduced in Rails 3.0.2, the above code works fine in Rails 3.0.1
-
Mark A. Richman
Thanks Iain! How do we get this fixed in 3.0.4?
-
Mark A. Richman
Would you mind pasting your json_test.rb so I can see what you did?
-
iain
json_test.rb is the code I showed (minus a "require 'config/environment'" line to load my Rails app).
To fix it, we need to dig in activesupport/lib/active_support/json/encoding.rb and see what has been changed. -
John Firebaugh
A custom #as_json definition should usually call Array#as_json or Hash#as_json itself. For example, the correct definition in the example above is:
class Base def as_json(*args) [ Sub.new ].as_json(*args) end endObject#as_json has a similar bug, which is causing Mark's exception. It should call #as_json on the result of #to_hash or #instance_values:
class Object def as_json(options = nil) #:nodoc: if respond_to?(:to_hash) to_hash else instance_values end.as_json(options) end end -
bgallet
I cannot reproduce this, however, it is not behaving as expected.
Struct.new("StructTest", :name, :address) puts Struct::StructTest.new("Dave", "value").to_json # => ["Dave","121 Main st."]I would have expected: { "name": "Dave", "address": "121 Main st." }
-
jasereja
I have same problem.
Use mongoid and try respond_to :jsonIn rails 3.0.1 it work nice. higher versions broken.
-
Alexey Nayden
Failing test
-
Alexey Nayden
A patch to fix complex structures #as_json and #to_json
-
Alexey Nayden
- Assigned user set to Jeremy Kemper
- Tag changed from as_json, encode_json, json, to_json to as_json, encode_json, json, patch, to_json
-
Neeraj Singh
- Milestone set to 3.x
- State changed from new to open
- Importance changed from to Low
Here is a patch with test.
https://github.com/neerajdotname/rails/commit/e9931f1df28eb97c53a92...
-
Neeraj Singh
sorry I did not see there was already a patch for it. Ignore me.
-
Alexey Nayden
@Neeraj no problem. So are you going to apply my patch? Or maybe I shall reassign the ticket to someone else?
-
Neeraj Singh
I can't apply your patch. Only core team can do that. I can +1 this ticket.
+1
-
Alexey Nayden
- Assigned user changed from Jeremy Kemper to Santiago Pastorino
-
Alexey Nayden
Santiago, would you please apply my patch? It seems to be useful bugfix.
-
Repository
- State changed from open to committed
(from [a9163b547c7cfd4861c814371fa9d1a6bdb31231]) Complex struct encoding fix
[#6077 ActiveSupport::JSON.encode fails for Struct types state:committed]
Signed-off-by: Santiago Pastorino santiago@wyeworks.com
https://github.com/rails/rails/commit/a9163b547c7cfd4861c814371fa9d... -
Bryce Kerley
I'm getting a test failure on this in 1.9.2-p136, due to hash ordering:
test_struct_encoding(TestJSONEncoding) [test/json/encoding_test.rb:239]: <"{\"sub\":{\"name\":\"David\",\"date\":\"2010/01/01\"},\"name\":\"David\"}"> expected but was <"{\"name\":\"David\",\"sub\":{\"name\":\"David\",\"date\":\"2010/01/01\"}}">.Should the expected struct ordering be canonical? If not, I've patched the expected ordering in the test at https://github.com/bkerley/rails/commit/b9d05c3fff974e59b4e06da68d9... .
-
Mike (at coverallcrew)
This is still failing for me with Rails 3.0.4
To replicate, try using Mongoid or MongoMapper with anything higher than Rails 3.0.1
-
Santiago Pastorino
Have you tried this against master?
I guess we haven't backported to 3-0-stable?
