Question
How can you convert a Ruby Hash object to JSON?
For example, why does the following code not work in some Ruby environments?
car = { :make => "bmw", :year => "2003" }
car.to_json
I noticed that Hash does not always appear to have a to_json method in plain Ruby documentation. However, many examples online show that Rails supports ActiveRecord#to_json and also Hash#to_json.
Since ActiveRecord is part of Rails but Hash is a core Ruby object, why can hash.to_json work in Rails but not always in plain Ruby?
Short Answer
By the end of this page, you will understand how JSON conversion works for Ruby hashes, why to_json may work automatically in Rails, and how to use the correct library in plain Ruby. You will also see the difference between to_json and JSON.generate, common mistakes, and practical examples.
Concept
JSON is a text format used to exchange structured data between programs. Ruby uses Hash objects to store key-value pairs, and JSON uses objects that look very similar.
For example:
{ name: "Alice", age: 30 }
becomes:
{"name":"Alice","age":30}
Although Ruby hashes and JSON objects look similar, they are not the same thing:
- A Ruby
Hashis an in-memory Ruby object. - JSON is a string.
That means converting a hash to JSON is really serialization: turning a Ruby object into a JSON-formatted string.
In plain Ruby, JSON support usually comes from the standard json library, which you must load first:
require 'json'
After that, Ruby can serialize hashes and other supported objects.
In Rails, many features are preloaded for you. Rails commonly adds or exposes methods like to_json in a way that feels automatic. That is why code may work in Rails without extra setup, but fail in a plain Ruby script unless you explicitly require the JSON library.
Mental Model
Think of a Ruby hash as a packed suitcase full of labeled items, and JSON as the shipping label format required by another system.
Inside your Ruby program, the suitcase can stay in Ruby form:
{ make: "bmw", year: "2003" }
But if you want to send that data to a browser, an API, or another service, you need to print it in the correct transport format:
{"make":"bmw","year":"2003"}
So to_json is like converting your suitcase contents into a standard label that other systems can read.
Syntax and Examples
The most common way in plain Ruby is to require the JSON library and then call to_json or use JSON.generate.
Basic example
require 'json'
car = { make: 'bmw', year: '2003' }
puts car.to_json
Output:
{"make":"bmw","year":"2003"}
Using JSON.generate
require 'json'
car = { make: 'bmw', year: '2003' }
puts JSON.generate(car)
This produces the same result.
Nested hash example
require 'json'
car = {
,
,
{
,
}
}
puts car.to_json
Step by Step Execution
Consider this example:
require 'json'
car = { make: 'bmw', year: '2003' }
json_text = car.to_json
puts json_text
Here is what happens step by step:
-
require 'json'- Ruby loads the JSON library.
- This adds JSON serialization support.
-
car = { make: 'bmw', year: '2003' }- A Ruby hash is created.
- It has two keys:
:makeand:year.
-
json_text = car.to_json- Ruby converts the hash into a JSON string.
- The result is not a hash anymore.
- It is now text:
"{\"make\":\"bmw\",\"year\":\"2003\"}" -
puts json_text- Ruby prints the JSON string in readable form:
Real World Use Cases
Converting a hash to JSON is common in many kinds of Ruby programs.
API responses
A web app often builds a hash and returns it as JSON:
response = { status: 'ok', user_id: 42 }
puts response.to_json
Sending data to another service
If your Ruby app calls an external API, it may need to send JSON in the request body.
payload = { email: 'user@example.com', active: true }
json_body = payload.to_json
Saving structured logs
Applications sometimes store log entries as JSON for easier searching.
log_entry = { level: 'info', message: 'User signed in' }
puts log_entry.to_json
Background jobs and queues
Job payloads are often serialized before being stored or transmitted.
job = { type: 'send_email', user_id: 7 }
serialized = job.to_json
Config export
A script may convert internal data into JSON for another tool to consume.
Real Codebase Usage
In real projects, developers often do more than call to_json directly.
Pattern: explicit serialization
In plain Ruby scripts, many developers prefer this:
require 'json'
JSON.generate(data)
Why:
- it makes the JSON dependency obvious
- it is clear that serialization is happening
- it avoids confusion about whether
to_jsonis available
Pattern: rendering JSON in Rails
In Rails controllers, developers usually return hashes as JSON through framework helpers:
render json: { status: 'ok', message: 'Saved' }
Rails handles serialization for you.
Pattern: building response hashes first
A common approach is:
- build a plain Ruby hash
- serialize it only at the boundary of the system
result = {
user: user.name,
admin: user.admin?
}
JSON.generate(result)
This keeps your internal logic Ruby-friendly.
Common Mistakes
1. Forgetting to load the JSON library
Broken code:
car = { make: 'bmw', year: '2003' }
car.to_json
Problem:
- In plain Ruby,
to_jsonmay not be available until you load JSON support.
Fix:
require 'json'
car = { make: 'bmw', year: '2003' }
car.to_json
2. Confusing a hash with a JSON string
Broken assumption:
car = { make: 'bmw' }
json_car = car.to_json
puts json_car[:make]
Problem:
json_caris a string, not a hash.- String indexing does not work like hash access.
Fix:
require 'json'
car = { make: 'bmw' }
json_car = car.to_json
puts json_car
Comparisons
| Approach | Works in plain Ruby? | Requires require 'json'? | Notes |
|---|---|---|---|
hash.to_json | Yes, usually after loading JSON | Yes | Convenient and common |
JSON.generate(hash) | Yes | Yes | Explicit and clear |
JSON.pretty_generate(hash) | Yes | Yes | Best for readable output |
render json: hash in Rails | Rails only | No manual require in normal Rails use | Rails handles serialization |
to_json vs JSON.generate
Cheat Sheet
require 'json'
Convert hash to JSON
car = { make: 'bmw', year: '2003' }
car.to_json
Explicit conversion
JSON.generate(car)
Pretty output
JSON.pretty_generate(car)
Key rules
- Ruby hash keys can be symbols or strings.
- JSON object keys are always strings.
- JSON output is a string, not a hash.
Common fix for undefined method 'to_json'
require 'json'
Good default in plain Ruby
require 'json'
JSON.generate(data)
Example
FAQ
Why does hash.to_json work in Rails but not in plain Ruby?
Rails often loads JSON-related functionality for you. In plain Ruby, you usually need require 'json' first.
What is the simplest way to convert a Ruby hash to JSON?
Use:
require 'json'
JSON.generate(hash)
or:
require 'json'
hash.to_json
Is to_json built into every Ruby object?
Not always in the way beginners expect. Availability depends on the loaded libraries and environment.
Are Ruby symbol keys preserved in JSON?
No. JSON object keys become strings.
What is the difference between a hash and a JSON string?
A hash is a Ruby data structure. JSON is text used to represent data.
Should I use to_json or JSON.generate?
In plain Ruby, JSON.generate is often clearer because it makes the conversion explicit.
How do I get formatted JSON output in Ruby?
Use:
Mini Project
Description
Build a small Ruby script that creates a product record as a hash and exports it as JSON. This demonstrates how Ruby data is prepared for APIs, files, or external services.
Goal
Create a Ruby script that turns a hash into both compact JSON and pretty-printed JSON.
Requirements
- Create a hash with at least three keys, such as name, price, and in_stock.
- Load the JSON library before converting the hash.
- Output both compact JSON and pretty-formatted JSON.
- Use valid Ruby variable names consistently.
Keep learning
Related questions
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.
Convert a Unix Timestamp to Ruby DateTime
Learn how to convert Unix timestamps to Ruby DateTime and Time objects, with examples, differences, pitfalls, and practical Ruby usage.