Question
I would like to format JSON output in Ruby on Rails so it is easier to read.
Right now, I call to_json, and the JSON is returned on a single line. This can make it hard to inspect the output and spot problems in the JSON stream.
Is there a way to configure Ruby on Rails so JSON is printed in a pretty, nicely formatted way?
Example:
data = { name: "Alice", age: 30, admin: true }
puts data.to_json
Short Answer
By the end of this page, you will understand how pretty-printed JSON works in Ruby and Ruby on Rails, why to_json usually returns compact JSON, and how to generate readable JSON for debugging, logs, and development tools using methods like JSON.pretty_generate.
Concept
JSON can be represented in two main ways:
- Compact JSON: everything on one line, with no extra spaces or indentation
- Pretty JSON: formatted with line breaks and indentation for readability
In Ruby on Rails, calling to_json usually produces compact JSON. That is useful for machines because it keeps the payload small, but it is harder for humans to read.
Pretty formatting matters when you want to:
- debug API responses
- inspect nested data structures
- read logs more easily
- compare JSON output during development
It is important to understand that pretty formatting changes the appearance, not the data itself. The JSON content is still the same. Only whitespace is added.
In Ruby, pretty-printing JSON is commonly done with the standard json library:
require 'json'
JSON.pretty_generate(hash)
This converts a Ruby hash or array into nicely indented JSON.
In Rails projects, this is often used for:
- debugging in the console
- rendering readable output in development
- logging structured data
For production API responses, developers often keep JSON compact because extra whitespace increases response size.
Mental Model
Think of JSON like a paragraph of text.
- Compact JSON is like one very long sentence with no line breaks.
- Pretty JSON is like the same text split into paragraphs and bullet points.
The meaning does not change. It just becomes easier for a human to scan.
So, pretty-printing JSON is like asking a computer to rewrite the same information in a cleaner layout.
Syntax and Examples
The most common way to pretty format JSON in Ruby is with JSON.pretty_generate.
require 'json'
data = {
name: "Alice",
age: 30,
admin: true,
skills: ["Ruby", "Rails"]
}
puts JSON.pretty_generate(data)
Output:
{
"name": "Alice",
"age": 30,
"admin": true,
"skills": [
"Ruby",
"Rails"
]
}
Using it with JSON strings
If you already have a JSON string, parse it first, then pretty print it:
json_string =
parsed = .parse(json_string)
puts .pretty_generate(parsed)
Step by Step Execution
Consider this example:
require 'json'
data = {
user: {
name: "Alice",
age: 30
},
active: true
}
pretty = JSON.pretty_generate(data)
puts pretty
Here is what happens step by step:
-
require 'json'- Loads Ruby's JSON library.
-
data = { ... }- Creates a Ruby hash containing nested data.
-
JSON.pretty_generate(data)- Ruby reads the hash.
- It converts the hash into valid JSON.
- It inserts indentation and line breaks.
- The result is a string.
-
pretty = ...- Stores that formatted JSON string in the
prettyvariable.
- Stores that formatted JSON string in the
-
puts pretty- Prints the formatted JSON to the terminal or log.
Real World Use Cases
Pretty-printed JSON is most useful when humans need to read it.
Debugging API responses
When building a Rails API, you may want to inspect nested objects:
puts JSON.pretty_generate(@order.as_json(include: :line_items))
Logging structured data
Readable logs are easier to troubleshoot:
Rails.logger.debug JSON.pretty_generate(payload)
Console inspection
In the Rails console, pretty JSON helps you understand complex objects:
puts JSON.pretty_generate(User.first.as_json)
Saving debug snapshots
You might save formatted JSON to a file while investigating an issue:
File.write("debug.json", JSON.pretty_generate(data))
Comparing outputs in tests or during development
Pretty formatting makes it easier to visually compare expected and actual JSON structures.
Real Codebase Usage
In real Rails codebases, developers usually separate data generation from display formatting.
Common pattern: build data with as_json
payload = @user.as_json(only: [:id, :name, :email])
Rails.logger.debug(JSON.pretty_generate(payload))
This avoids mixing serialization logic with presentation.
Guard clause for optional debug output
payload = @user.as_json
if Rails.env.development?
puts JSON.pretty_generate(payload)
end
This keeps pretty output limited to development.
Error investigation
When handling failures, developers often log a readable payload:
begin
process_payload(payload)
rescue => e
Rails.logger.error(e.message)
Rails.logger.error(JSON.pretty_generate(payload))
end
Configuration awareness
Pretty JSON is usually not enabled globally for all responses in production because:
Common Mistakes
1. Using to_json and expecting pretty output
data = { name: "Alice" }
puts data.to_json
This usually outputs compact JSON on one line.
Fix:
require 'json'
puts JSON.pretty_generate(data)
2. Pretty-printing an already encoded JSON string incorrectly
Broken example:
json_string = '{"name":"Alice"}'
puts JSON.pretty_generate(json_string)
This treats the whole string as a plain Ruby string, not as parsed JSON data.
Fix:
parsed = JSON.parse(json_string)
puts JSON.pretty_generate(parsed)
3. Confusing as_json with to_json
as_jsonreturns a Ruby hash or arrayto_jsonreturns a JSON string
Comparisons
| Approach | What it returns | Readable for humans | Best use |
|---|---|---|---|
to_json | JSON string | No, usually compact | API responses, serialization |
as_json | Ruby hash/array | Somewhat | Preparing data before rendering |
JSON.pretty_generate(obj) | Pretty JSON string | Yes | Debugging, logging, inspection |
JSON.parse(json_string) | Ruby hash/array from JSON string | N/A | Reading existing JSON |
as_json vs to_json
Cheat Sheet
require 'json'
Pretty print a Ruby hash
JSON.pretty_generate(data)
Pretty print a Rails object
JSON.pretty_generate(@user.as_json)
Pretty print an existing JSON string
parsed = JSON.parse(json_string)
JSON.pretty_generate(parsed)
Key rules
to_json-> returns a JSON stringas_json-> returns a Ruby hash or arrayJSON.pretty_generate(...)-> returns formatted JSON string- Pretty formatting changes whitespace only, not the actual data
- Use pretty JSON mainly for debugging, logs, and development
Common pattern
payload = object.as_json
puts JSON.pretty_generate(payload)
Watch out for
- Passing a raw JSON string directly to
FAQ
How do I pretty print JSON in Ruby on Rails?
Use Ruby's JSON library with JSON.pretty_generate:
JSON.pretty_generate(@object.as_json)
Why does to_json return one line?
to_json is designed to generate compact JSON by default. This is efficient for machines and network responses.
Should I use pretty JSON in production APIs?
Usually no. Pretty JSON is easier for humans to read, but it increases response size. Most production APIs use compact JSON.
What is the difference between as_json and to_json in Rails?
as_json returns a Ruby structure, while to_json returns a JSON string.
Can I pretty print a JSON string I already have?
Yes. First parse it, then pretty print it:
JSON.pretty_generate(JSON.parse(json_string))
Does pretty formatting change the JSON data?
No. It only adds spaces and line breaks for readability.
Can I use pretty JSON for logging?
Mini Project
Description
Build a small Rails-style JSON debugging script that takes a Ruby hash representing an API response and prints both compact and pretty-formatted JSON. This demonstrates the difference between machine-friendly output and human-friendly output, which is useful when debugging controllers, background jobs, or external API payloads.
Goal
Create a Ruby script that generates JSON data and prints a readable version using proper pretty formatting.
Requirements
- Create a Ruby hash with nested data such as a user and a list of roles.
- Print the compact JSON using
to_json. - Print the formatted JSON using
JSON.pretty_generate. - Include at least one nested object or array.
- Show the difference clearly in the output.
Keep learning
Related questions
How to Call Shell Commands from Ruby and Capture Output
Learn how to run shell commands in Ruby, capture output, check exit status, and choose the right method for scripts and apps.
How to Check Whether a String Contains a Substring in Ruby
Learn how to check if a string contains a substring in Ruby using include?, match, and multiline string examples.
How to Check if a Hash Key Exists in Ruby
Learn how to check whether a specific key exists in a Ruby hash using key?, has_key?, and include? with clear examples.