Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

#to_json behavior still different between Rails 2.3.2.1 and Rails 2-3-stable

#2753

Ticket #2690 #to_json not working because always being called on Object helped the problems with to_json serialization in the Rails 2.3 branch, but the behavior of to_json is still different between Rails 2.3.2.1 and Rails 2.3-stable. The following example illustrates the problem:

class A
  def initialize
    @a, @b = 1, 2
  end
  
  def to_json(options = {})
    @a.to_json(options)
  end
end

class B
  def initialize
    @a = A.new
  end
end

In Rails 2.3.2.1 the output is the following:

b = B.new
b.to_json #=> {"a": 1}

In Rails 2.3-stable the output is:

b = B.new
b.to_json #=> {"a":{"a":1,"b":2}}

The problem is caused by ActiveSupport::JSON.encode calling rails_to_json instead of to_json on the objects. Overridden to_json() methods child objects are never called.

Going forward all objects will have to have a rails_to_json() method, but the problem is that this functionality changed in the stable 2-3 branch.

In Shopify we have monkey patched active_support/json/encoding.rb to call value.to_json() instead of value.rails_to_json() to achieve the same output from Rails 2.3.2.1.

Reported by Cody Fauser · June 3rd, 2009 @ 04:17 PM

State: resolved
Milestone: 2.3.3
Assigned to: Jeremy Kemper Jeremy Kemper
Importance: High

Activity

  1. Michael Koziarski
    Michael Koziarski
    • Assigned user set to Rick

    Given this I think we have no choice but to revert the rails_to_json change from 2-3-stable and figure out a plan for deprecation.

    It can remain in master of course.

    June 3rd, 2009 @ 09:23 PM

  2. Michael Koziarski
    Michael Koziarski
    • Milestone changed from 2.x to 2.3.3

    June 6th, 2009 @ 05:05 AM

  3. Jeremy Kemper
    Jeremy Kemper
    • State changed from new to open
    • Assigned user changed from Rick to Jeremy Kemper

    What a headache. Overriding to_json to provide custom JSON representations is a bad API decision. Instead we should be overriding a dump_json method to provide a Hash, Array, etc to encode. Then we don't have to walk the path of

    class Custom
      def to_json(*strange_internal_state)

    { :alternate => 'representation' }.to_json(*strange_internal_state)
    
    
    
    
    end end
    Instead we have the much cleaner
    class Custom
      def dump_json(options_hash)

    { :alternate => 'representation' }
    
    
    
    
    end end
    I'm reverting the change in 2-3-stable but will move to this new API in master.

    June 7th, 2009 @ 12:32 AM

  4. Michael Koziarski
    Michael Koziarski

    Sounds like an improvement for sure. Not sold on the name, but it
    beats the 'return a json string' api that's very brittle.

    When you revert this from 2-3-stable move this ticket's milestone to 3.0

    June 7th, 2009 @ 04:44 AM

  5. Jeremy Kemper
    Jeremy Kemper

    The naming mirrors Marshal's choice of marshal_dump/load

    June 7th, 2009 @ 06:12 AM

  6. Repository