Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

renderer calls object.to_json when rendering :json => object [#5655 s…

…tate:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information...
commit 72f37bd8bc5b3beb1e8a2d1ac2de2c045cd0cfd2 1 parent 4966b91
@dcrec1 dcrec1 authored josevalim committed
View
2  actionpack/lib/action_controller/metal/renderers.rb
@@ -71,7 +71,7 @@ def self._write_render_options
end
add :json do |json, options|
- json = ActiveSupport::JSON.encode(json, options) unless json.respond_to?(:to_str)
+ json = json.to_json(options) unless json.respond_to?(:to_str)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
self.content_type ||= Mime::JSON
self.response_body = json
View
13 actionpack/test/controller/render_json_test.rb
@@ -9,6 +9,10 @@ def as_json(options={})
hash.except!(*options[:except]) if options[:except]
hash
end
+
+ def to_json(options = {})
+ super :except => [:c, :e]
+ end
end
class TestController < ActionController::Base
@@ -49,6 +53,10 @@ def render_json_with_render_to_string
def render_json_with_extra_options
render :json => JsonRenderable.new, :except => [:c, :e]
end
+
+ def render_json_without_options
+ render :json => JsonRenderable.new
+ end
end
tests TestController
@@ -109,4 +117,9 @@ def test_render_json_forwards_extra_options
assert_equal '{"a":"b"}', @response.body
assert_equal 'application/json', @response.content_type
end
+
+ def test_render_json_calls_to_json_from_object
+ get :render_json_without_options
+ assert_equal '{"a":"b"}', @response.body
+ end
end

3 comments on commit 72f37bd

@brianmario

I thought we were trying to get rid of to_json entirely? (or as much as possible at least)

@dcrec1

what is the problem with to_json?

@brianmario

The JSON gem, ActiveSupport and yajl-ruby's JSON gem compatibility API all override that method. If someone includes 'yajl/json_gem' after ActiveSupport has been loaded, the above code will work but not the way the caller expects since the options hash for ActiveSupport's version of to_json is completely different than that of the one in yajl-ruby's JSON gem compatibility API.

I was under the assumption as_json was added to help get around this by allowing one to provide a JSON encodable version of their object using primitives that are directly mappable to JSON from Ruby, and the other way around. Then to actually encode the object, it would be passed through ActiveSupport::JSON.encode which has no chance of being overridden elsewhere and as such would have consistent behavior everywhere.

Rails actually has a hack for this from long-standing issues in the past with the JSON gem and ActiveSupport both overriding to_json.

Please sign in to comment.
Something went wrong with that request. Please try again.