3

Ruby on Rails adds the "as_json" method to many common classes, which turns ActiveRecord objects into hash objects that can then be sent to a JSON serializer. Recently I encountered a bug in my code related to this method and it's treatment of boolean values.

I can summarize the bug very concisely:

{"foo" => true}.as_json

I would expect this method to return an identical hash. Instead, it returns

{"foo" => "true"}

This appears to be by design, as per line 157 in encoding.rb

AS_JSON = ActiveSupport::JSON::Variable.new('true').freeze

Can I ask, why is rails returning the string value "true" instead of keeping it as a true boolean value?

My bug is as follows: I keep JSON-serialized objects in a cache. When I pull them out of the cache I leave them as hashes to avoid unnecessary object deserialization. If I don't find it in the cache, I pull the object out of the database and call as_json on it. I expect what I pull out of the cache and what I get back from as_json to be identical. They're not, because what comes out of the cache is {"foo" => true} and what comes back from as_json is {"foo" => "true"}

1 Answer 1

1

That's the way it's implemented.

You could change the default behavior putting this in an initializer:

class TrueClass
  def as_json(*options)
    self
  end
end

class FalseClass
  def as_json(*options)
    self
  end
end
Sign up to request clarification or add additional context in comments.

2 Comments

Right, I know that is how it is implemented, but not knowing the justification I am wary of changing its behavior lest I break another component.
I don't think there is any json exchange within Rails so you shoudn't fear this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.