A summary of data about the Ruby ecosystem.

https://github.com/rails/jbuilder

Jbuilder: generate JSON objects with a Builder-style DSL
https://github.com/rails/jbuilder

Keywords from Contributors

activerecord activejob mvc rubygems rack ruby-gem rspec rubocop crash-reporting sinatra

Last synced: about 13 hours ago
JSON representation

Repository metadata

Jbuilder: generate JSON objects with a Builder-style DSL

README.md

Jbuilder

Jbuilder gives you a simple DSL for declaring JSON structures that beats
manipulating giant hash structures. This is particularly helpful when the
generation process is fraught with conditionals and loops. Here's a simple
example:

# app/views/messages/show.json.jbuilder

json.content format_content(@message.content)
json.(@message, :created_at, :updated_at)

json.author do
  json.name @message.creator.name.familiar
  json.email_address @message.creator.email_address_with_name
  json.url url_for(@message.creator, format: :json)
end

if current_user.admin?
  json.visitors calculate_visitors(@message)
end

json.comments @message.comments, :content, :created_at

json.attachments @message.attachments do |attachment|
  json.filename attachment.filename
  json.url url_for(attachment)
end

This will build the following structure:

{
  "content": "<p>This is <i>serious</i> monkey business</p>",
  "created_at": "2011-10-29T20:45:28-05:00",
  "updated_at": "2011-10-29T20:45:28-05:00",

  "author": {
    "name": "David H.",
    "email_address": "'David Heinemeier Hansson' <david@heinemeierhansson.com>",
    "url": "http://example.com/users/1-david.json"
  },

  "visitors": 15,

  "comments": [
    { "content": "Hello everyone!", "created_at": "2011-10-29T20:45:28-05:00" },
    { "content": "To you my good sir!", "created_at": "2011-10-29T20:47:28-05:00" }
  ],

  "attachments": [
    { "filename": "forecast.xls", "url": "http://example.com/downloads/forecast.xls" },
    { "filename": "presentation.pdf", "url": "http://example.com/downloads/presentation.pdf" }
  ]
}

Dynamically Defined Attributes

To define attribute and structure names dynamically, use the set! method:

json.set! :author do
  json.set! :name, 'David'
end

# => {"author": { "name": "David" }}

Merging Existing Hash or Array

To merge existing hash or array to current context:

hash = { author: { name: "David" } }
json.post do
  json.title "Merge HOWTO"
  json.merge! hash
end

# => "post": { "title": "Merge HOWTO", "author": { "name": "David" } }

Top Level Arrays

Top level arrays can be handled directly. Useful for index and other collection actions.

# @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": "Bloe" }} ]

Array Attributes

You can also extract attributes from array directly.

# @people = People.all

json.array! @people, :id, :name

# => [ { "id": 1, "name": "David" }, { "id": 2, "name": "Jamie" } ]

Plain Arrays

To make a plain array without keys, construct and pass in a standard Ruby array.

my_array = %w(David Jamie)

json.people my_array

# => "people": [ "David", "Jamie" ]

Child Objects

You don't always have or need a collection when building an array.

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" } ] }

Nested Jbuilder Objects

Jbuilder objects can be directly nested inside each other. Useful for composing objects.

class Person
  # ... Class Definition ... #
  def to_builder
    Jbuilder.new do |person|
      person.(self, :name, :age)
    end
  end
end

class Company
  # ... Class Definition ... #
  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}}

Rails Integration

You can either use Jbuilder stand-alone or directly as an ActionView template
language. When required in Rails, you can create views à la show.json.jbuilder
(the json is already yielded):

# Any helpers available to views are available to the builder
json.content format_content(@message.content)
json.(@message, :created_at, :updated_at)

json.author do
  json.name @message.creator.name.familiar
  json.email_address @message.creator.email_address_with_name
  json.url url_for(@message.creator, format: :json)
end

if current_user.admin?
  json.visitors calculate_visitors(@message)
end

Partials

You can use partials as well. The following will render the file
views/comments/_comments.json.jbuilder, and set a local variable
comments with all this message's comments, which you can use inside
the partial.

json.partial! 'comments/comments', comments: @message.comments

It's also possible to render collections of partials:

json.array! @posts, partial: 'posts/post', as: :post

# or
json.partial! 'posts/post', collection: @posts, as: :post

# or
json.partial! partial: 'posts/post', collection: @posts, as: :post

# or
json.comments @post.comments, partial: 'comments/comment', as: :comment

The as: :some_symbol is used with partials. It will take care of mapping the passed in object to a variable for the
partial. If the value is a collection either implicitly or explicitly by using the collection: option, then each
value of the collection is passed to the partial as the variable some_symbol. If the value is a singular object,
then the object is passed to the partial as the variable some_symbol.

Be sure not to confuse the as: option to mean nesting of the partial. For example:

# Use the default `views/comments/_comment.json.jbuilder`, putting @comment as the comment local variable.
# Note, `comment` attributes are "inlined".
json.partial! @comment, as: :comment

is quite different from:

# comment attributes are nested under a "comment" property
json.comment do
  json.partial! "/comments/comment.json.jbuilder", comment: @comment
end

You can pass any objects into partial templates with or without :locals option.

json.partial! 'sub_template', locals: { user: user }

# or

json.partial! 'sub_template', user: user

Null Values

You can explicitly make Jbuilder object return null if you want:

json.extract! @post, :id, :title, :content, :published_at
json.author do
  if @post.anonymous?
    json.null! # or json.nil!
  else
    json.first_name @post.author_first_name
    json.last_name @post.author_last_name
  end
end

To prevent Jbuilder from including null values in the output, you can use the ignore_nil! method:

json.ignore_nil!
json.foo nil
json.bar "bar"
# => { "bar": "bar" }

Caching

Fragment caching is supported, it uses Rails.cache and works like caching in
HTML templates:

json.cache! ['v1', @person], expires_in: 10.minutes do
  json.extract! @person, :name, :age
end

You can also conditionally cache a block by using cache_if! like this:

json.cache_if! !admin?, ['v1', @person], expires_in: 10.minutes do
  json.extract! @person, :name, :age
end

Aside from that, the :cached options on collection rendering is available on Rails >= 6.0. This will cache the
rendered results effectively using the multi fetch feature.

json.array! @posts, partial: "posts/post", as: :post, cached: true

# or:
json.comments @post.comments, partial: "comments/comment", as: :comment, cached: true

If your collection cache depends on multiple sources (try to avoid this to keep things simple), you can name all these dependencies as part of a block that returns an array:

json.array! @posts, partial: "posts/post", as: :post, cached: -> post { [post, current_user] }

This will include both records as part of the cache key and updating either of them will expire the cache.

Formatting Keys

Keys can be auto formatted using key_format!, this can be used to convert
keynames from the standard ruby_format to camelCase:

json.key_format! camelize: :lower
json.first_name 'David'

# => { "firstName": "David" }

You can set this globally with the class method key_format (from inside your
environment.rb for example):

Jbuilder.key_format camelize: :lower

By default, key format is not applied to keys of hashes that are
passed to methods like set!, array! or merge!. You can opt into
deeply transforming these as well:

json.key_format! camelize: :lower
json.deep_format_keys!
json.settings([{some_value: "abc"}])

# => { "settings": [{ "someValue": "abc" }]}

You can set this globally with the class method deep_format_keys (from inside your
environment.rb for example):

Jbuilder.deep_format_keys true

Testing JBuilder Response body with RSpec

To test the response body of your controller spec, enable render_views in your RSpec context. This configuration renders the views in a controller test.

Contributing to Jbuilder

Jbuilder is the work of many contributors. You're encouraged to submit pull requests, propose
features and discuss issues.

See CONTRIBUTING.

License

Jbuilder is released under the MIT License.


Owner metadata


GitHub Events

Total
Last Year

Committers metadata

Last synced: 2 days ago

Total Commits: 677
Total Committers: 144
Avg Commits per committer: 4.701
Development Distribution Score (DDS): 0.638

Commits in past year: 44
Committers in past year: 5
Avg Commits per committer in past year: 8.8
Development Distribution Score (DDS) in past year: 0.25

Name Email Commits
Pavel Pravosud p****l@p****m 245
David Heinemeier Hansson d****d@l****m 82
Michael Oberegger m****r@a****o 33
Rolf Timmermans r****s@v****m 30
Akira Matsuda r****e@d****p 27
George Claghorn g****e@b****m 19
Rafael Mendonça França r****l@r****g 16
Andrew White a****e@u****o 14
Jason Webb b****b@g****m 10
Olle Jonsson o****n@g****m 10
Ryan Garver r****r@g****m 9
Yuki Nishijima y****4@h****m 7
Vincent Woo me@v****m 4
Santiago Pastorino s****o@w****m 4
Nick Ragaz n****z@g****m 4
Jeremy Daer j****r@g****m 4
El Jeffo m****e@r****m 4
claudiob c****b@g****m 4
Chris Oliver e****3@g****m 4
Peter Goldstein p****n@g****m 3
Jon Moss me@j****e 3
Robin Dupret r****t@g****m 3
Jorge Bejar j****e@w****m 3
Jerome Dalbert j****t@g****m 3
Javan Makhmali j****n@j****s 3
Hernán Schmidt l****o@g****m 3
Jayme Deffenbaugh j****h@m****m 2
John Bampton j****n 2
Yasuharu Ozaki y****i@g****m 2
chrisxue815 c****5@g****m 2
and 114 more...

Committer domains:


Issue and Pull Request metadata

Last synced: 7 days ago

Total issues: 61
Total pull requests: 123
Average time to close issues: 6 months
Average time to close pull requests: 6 months
Total issue authors: 61
Total pull request authors: 65
Average comments per issue: 4.26
Average comments per pull request: 1.15
Merged pull request: 64
Bot issues: 0
Bot pull requests: 0

Past year issues: 2
Past year pull requests: 30
Past year average time to close issues: 28 days
Past year average time to close pull requests: 25 days
Past year issue authors: 2
Past year pull request authors: 6
Past year average comments per issue: 0.5
Past year average comments per pull request: 0.27
Past year merged pull request: 8
Past year bot issues: 0
Past year bot pull requests: 0

More stats: https://issues.ecosyste.ms/repositories/lookup?url=https://github.com/rails/jbuilder

Top Issue Authors

  • rianfloo (1)
  • cupakromer (1)
  • bborn (1)
  • gsmetal (1)
  • robinvdvleuten (1)
  • goulvench (1)
  • qichunren (1)
  • shettytejas (1)
  • dvodvo (1)
  • jtannas (1)
  • dekhaus (1)
  • Narf-stack (1)
  • aruprakshit (1)
  • watzon (1)
  • SunnyTam (1)

Top Pull Request Authors

  • moberegger (22)
  • excid3 (7)
  • jeromedalbert (5)
  • yuki24 (5)
  • pixeltrix (3)
  • petergoldstein (3)
  • seanpdoyle (2)
  • yahonda (2)
  • ldeld (2)
  • RubenLopSol (2)
  • richardvenneman (2)
  • mtsmfm (2)
  • olleolleolle (2)
  • Earlopain (2)
  • jbampton (2)

Top Issue Labels

  • bug (4)
  • attached PR (2)
  • feature (2)

Top Pull Request Labels


Package metadata

gem.coop: jbuilder

Create JSON structures via a Builder-style DSL

rubygems.org: jbuilder

Create JSON structures via a Builder-style DSL

proxy.golang.org: github.com/rails/jbuilder

  • Homepage:
  • Documentation: https://pkg.go.dev/github.com/rails/jbuilder#section-documentation
  • Licenses: mit
  • Latest release: v2.14.1+incompatible (published 4 months ago)
  • Last Synced: 2025-12-14T10:05:57.795Z (3 days ago)
  • Versions: 74
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Stargazers count: 1.019%
    • Forks count: 1.395%
    • Average: 5.698%
    • Dependent packages count: 9.576%
    • Dependent repos count: 10.802%

Dependencies

Gemfile rubygems
  • appraisal >= 0
  • mocha >= 0
  • rake >= 0
jbuilder.gemspec rubygems
  • json >= 0 development
  • racc >= 0 development
  • rubysl >= 0 development
  • actionview >= 5.0.0
  • activesupport >= 5.0.0
.github/workflows/ruby.yml actions
  • actions/checkout v2 composite
  • ruby/setup-ruby v1 composite

Score: 33.80594694611946