Jbuilder Documentation

repository·main·Indexed 26 days ago

https://github.com/rails/jbuilder

A JSON building DSL for Ruby commonly used in Rails applications to construct complex JSON structures. It provides a declarative syntax for transforming models and hashes into JSON responses, featuring tools for dynamic attribute definition with `set!`, collection handling via `array!`, partial rendering, fragment caching with `cache!`, and key formatting such as camelCase transformation.

Tokens
3.2K
Snippets
14
Records
26
Agent score
87%

What's inside Jbuilder

  1. Use partials in Jbuilder

    main

    Jbuilder supports rendering partials. You can render a partial with specific locals, render an object to a partial under a key, or render collections of partials.

    Key options:

    • locals: A hash of variables to pass to the partial.
    • as: Maps the object (or collection item) to a specific variable name within the partial.
    • collection: Used to render a collection of partials.

    Note: as: defines the variable name in the partial, it does not define the nesting level of the JSON output.

    # Render a partial with locals
    json.partial! 'sub_template', locals: { user: user }
    # or
    json.partial! 'sub_template', user: user
    
    # Render an object to a partial under a key
    json.post @post, partial: 'posts/post', as: :post
    
    # Render collections of partials
    json.array! @posts, partial: 'posts/post', as: :post
    json.partial! 'posts/post', collection: @posts, as: :post
    
    # Render collections of partials under a key
    json.comments @post.comments, partial: 'comments/comment', as: :comment
  2. Merge existing Hash or Array into current context

    main

    Use merge! to incorporate an existing Ruby Hash or Array into the current Jbuilder context.

    hash = { author: { name: "David" } }
    json.post do
      json.title "Merge HOWTO"
      json.merge! hash
    end
    
    # => "post": { "title": "Merge HOWTO", "author": { "name": "David" } }
  3. Create plain arrays without keys

    main

    To create a JSON array containing plain values (without key-value pairs), pass a standard Ruby array to a Jbuilder attribute.

    my_array = %w(David Jamie)
    
    json.people my_array
    
    # => "people": [ "David", "Jamie" ]
  4. Build arrays of child objects manually

    main

    If you do not have a collection but want to build an array of objects, use json.child! inside a block.

    json.people do
      json.child! do
        json.id 1
        json.name 'David'
      end
      json.child! do
        json.id 2
        json.name 'Jamie'
      end
    end
    
    # => { "people": [ { "id": 1, "name": "David" }, { "id": 2, "name": "Jamie" } ] }
  5. Create top-level arrays

    main

    To create a top-level JSON array (useful for index actions), use json.array!. You can pass a block to define the structure of each element in the array.

    # @comments = @post.comments
    
    json.array! @comments do |comment|
      next if comment.marked_as_spam_by?(current_user)
    
      json.body comment.body
      json.author do
        json.first_name comment.author.first_name
        json.last_name comment.author.last_name
      end
    end
    
    # => [ { "body": "great post...", "author": { "first_name": "Joe", "last_name": "Blow" }} ]
  6. Extract attributes from an array directly

    main

    You can use json.array! to quickly extract a specific set of attributes from a collection of objects.

    # @people = People.all
    
    json.array! @people, :id, :name
    
    # => [ { "id": 1, "name": "David" }, { "id": 2, "name": "Jamie" } ]
  7. Define JSON attributes dynamically with `set!`

    main

    Use the set! method to define attribute and structure names dynamically when the key name is not known at compile time.

    json.set! :author do
      json.set! :name, 'David'
    end
    
    # => {"author": {"name": "David"}}
  8. Format JSON keys (camelCase)

    main

    Use key_format! to automatically transform keys (e.g., from snake_case to camelCase).

    • camelize: :lower converts first_name to firstName.
    • Use deep_format_keys! to ensure keys inside nested hashes or arrays are also transformed.

    You can set these globally in your environment configuration using Jbuilder.key_format or Jbuilder.deep_format_keys.

    # Local formatting
    json.key_format! camelize: :lower
    json.first_name 'David'
    # => { "firstName": "David" }
    
    # Deep formatting for nested structures
    json.key_format! camelize: :lower
    json.deep_format_keys!
    json.settings([{some_value: "abc"}])
    # => { "settings": [{ "someValue": "abc" }]}
    
    # Global configuration (e.g., in environment.rb)
    Jbuilder.key_format camelize: :lower
    Jbuilder.deep_format_keys true
  9. Nest Jbuilder objects

    main

    Jbuilder objects can be composed by nesting them. A class can implement a to_builder method that returns a Jbuilder instance, which can then be used within another builder.

    class Person
      def to_builder
        Jbuilder.new do |person|
          person.(self, :name, :age)
        end
      end
    end
    
    class Company
      def to_builder
        Jbuilder.new do |company|
          company.name name
          company.president president.to_builder
        end
      end
    end
    
    company = Company.new('Doodle Corp', Person.new('John Stobs', 58))
    company.to_builder.target!
    
    # => {"name":"Doodle Corp","president":{"name":"John Stobs","age":58}}
  10. Cache Jbuilder fragments

    main

    Jbuilder supports fragment caching using Rails.cache. You can cache a block of code using json.cache! or conditionally cache using json.cache_if!. For Rails >= 6.0, you can use the cached: true option when rendering collections to leverage multi-fetch.

    # Basic fragment caching
    json.cache! ['v1', @person], expires_in: 10.minutes do
      json.extract! @person, :name, :age
    end
    
    # Conditional caching
    json.cache_if! !admin?, ['v1', @person], expires_in: 10.minutes do
      json.extract! @person, :name, :age
    end
    
    # Collection caching (Rails >= 6.0)
    json.array! @posts, partial: "posts/post", as: :post, cached: true
    
    # Collection caching with dynamic dependencies
    json.array! @posts, partial: "posts/post", as: :post, cached: -> post { [post, current_user] }
  11. Handle null values in JSON

    main

    You can explicitly return null using json.null! or json.nil!. To prevent Jbuilder from including any keys with nil values in the final output, use json.ignore_nil!.

    # Explicit null
    json.author do
      if @post.anonymous?
        json.null!
      end
    end
    
    # Prevent all nil values from being included
    json.ignore_nil!
    json.foo nil
    json.bar "bar"
    # => { "bar": "bar" }