Question

Pretty Formatting JSON Output in Ruby on Rails

rubyruby-on-railsjsonpretty-print

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.

Take Quiz

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:

require 'json'

json_string = '{"name":"Alice","age":30,"admin":true}'
parsed = JSON.parse(json_string)

puts JSON.pretty_generate(parsed)

In a Rails controller

If you want readable JSON for debugging inside a controller:

render plain: JSON.pretty_generate(@user.as_json)

If you want to preserve an actual JSON response body while formatting it manually:

render json: JSON.pretty_generate(@user.as_json)

However, in real Rails APIs, it is more common to let Rails render JSON normally and only pretty print during debugging or logging.

to_json vs as_json

A common Rails pattern is:

  • as_json returns a Ruby structure ready for JSON conversion
  • to_json returns the JSON string

Example:

user_hash = @user.as_json
pretty_json = JSON.pretty_generate(user_hash)
puts pretty_json

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:

  1. require 'json'

    • Loads Ruby's JSON library.
  2. data = { ... }

    • Creates a Ruby hash containing nested data.
  3. 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.
  4. pretty = ...

    • Stores that formatted JSON string in the pretty variable.
  5. puts pretty

    • Prints the formatted JSON to the terminal or log.

Final output:

{
  "user": {
    "name": "Alice",
    "age": 30
  },
  "active": true
}

Notice that the nested user object is indented, which makes the structure much easier to inspect.

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.

Take Quiz

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:

  • it increases response size
  • it is unnecessary for clients that parse JSON automatically
  • compact JSON is more efficient over the network

Serializer usage

In larger Rails apps, data may come from serializers, Jbuilder, or API frameworks. Even then, pretty formatting is still commonly applied only for debugging and development output.

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_json returns a Ruby hash or array
  • to_json returns a JSON string

If you want to pretty print, as_json is often the better starting point:

puts JSON.pretty_generate(@user.as_json)

4. Pretty-printing every production response

This works, but is often a bad idea for APIs under load because of larger payloads.

Better approach:

  • pretty print in development
  • keep production responses compact unless readability is specifically needed

5. Forgetting to require the JSON library in plain Ruby

In Rails, JSON support is usually available, but in plain Ruby scripts you may need:

require 'json'

Comparisons

ApproachWhat it returnsReadable for humansBest use
to_jsonJSON stringNo, usually compactAPI responses, serialization
as_jsonRuby hash/arraySomewhatPreparing data before rendering
JSON.pretty_generate(obj)Pretty JSON stringYesDebugging, logging, inspection
JSON.parse(json_string)Ruby hash/array from JSON stringN/AReading existing JSON

as_json vs to_json

MethodResultTypical Rails use
as_jsonRuby data structureModify or inspect data before encoding
to_jsonJSON stringSend JSON output directly

Compact vs pretty JSON

FormatAdvantageDisadvantage
Compact JSONSmaller payloadHarder to read
Pretty JSONEasier to debugLarger payload
Take Quiz

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 string
  • as_json -> returns a Ruby hash or array
  • JSON.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 pretty_generate
  • Assuming pretty output is enabled globally by default
  • Using pretty JSON for all production API responses unnecessarily

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?

Yes. It is a common way to make logs easier to inspect during development and debugging.

Take Quiz

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.
Take Quiz

Keep learning

Related questions

View more