[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7765":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":24,"readmeContent":25,"aiSummary":26,"trendingCount":16,"starSnapshotCount":16,"syncStatus":27,"lastSyncTime":28,"discoverSource":29},7765,"jbuilder","rails\u002Fjbuilder","rails","Jbuilder: generate JSON objects with a Builder-style DSL","",null,"Ruby",4413,450,84,33,0,3,29.96,"MIT License",false,"main",true,[],"2026-06-12 02:01:44","# Jbuilder\n\nJbuilder gives you a simple DSL for declaring JSON structures that beats\nmanipulating giant hash structures. This is particularly helpful when the\ngeneration process is fraught with conditionals and loops. Here's a simple\nexample:\n\n```ruby\n# app\u002Fviews\u002Fmessages\u002Fshow.json.jbuilder\n\njson.content format_content(@message.content)\njson.(@message, :created_at, :updated_at)\n\njson.author do\n  json.name @message.creator.name.familiar\n  json.email_address @message.creator.email_address_with_name\n  json.url url_for(@message.creator, format: :json)\nend\n\nif current_user.admin?\n  json.visitors calculate_visitors(@message)\nend\n\njson.comments @message.comments, :content, :created_at\n\njson.attachments @message.attachments do |attachment|\n  json.filename attachment.filename\n  json.url url_for(attachment)\nend\n```\n\nThis will build the following structure:\n\n```javascript\n{\n  \"content\": \"\u003Cp>This is \u003Ci>serious\u003C\u002Fi> monkey business\u003C\u002Fp>\",\n  \"created_at\": \"2011-10-29T20:45:28-05:00\",\n  \"updated_at\": \"2011-10-29T20:45:28-05:00\",\n\n  \"author\": {\n    \"name\": \"David H.\",\n    \"email_address\": \"'David Heinemeier Hansson' \u003Cdavid@heinemeierhansson.com>\",\n    \"url\": \"http:\u002F\u002Fexample.com\u002Fusers\u002F1-david.json\"\n  },\n\n  \"visitors\": 15,\n\n  \"comments\": [\n    { \"content\": \"Hello everyone!\", \"created_at\": \"2011-10-29T20:45:28-05:00\" },\n    { \"content\": \"To you my good sir!\", \"created_at\": \"2011-10-29T20:47:28-05:00\" }\n  ],\n\n  \"attachments\": [\n    { \"filename\": \"forecast.xls\", \"url\": \"http:\u002F\u002Fexample.com\u002Fdownloads\u002Fforecast.xls\" },\n    { \"filename\": \"presentation.pdf\", \"url\": \"http:\u002F\u002Fexample.com\u002Fdownloads\u002Fpresentation.pdf\" }\n  ]\n}\n```\n\n## Dynamically Defined Attributes\n\nTo define attribute and structure names dynamically, use the `set!` method:\n\n```ruby\njson.set! :author do\n  json.set! :name, 'David'\nend\n\n# => {\"author\": { \"name\": \"David\" }}\n```\n\n## Merging Existing Hash or Array\n\nTo merge existing hash or array to current context:\n\n```ruby\nhash = { author: { name: \"David\" } }\njson.post do\n  json.title \"Merge HOWTO\"\n  json.merge! hash\nend\n\n# => \"post\": { \"title\": \"Merge HOWTO\", \"author\": { \"name\": \"David\" } }\n```\n\n## Top Level Arrays\n\nTop level arrays can be handled directly. Useful for index and other collection actions.\n\n```ruby\n# @comments = @post.comments\n\njson.array! @comments do |comment|\n  next if comment.marked_as_spam_by?(current_user)\n\n  json.body comment.body\n  json.author do\n    json.first_name comment.author.first_name\n    json.last_name comment.author.last_name\n  end\nend\n\n# => [ { \"body\": \"great post...\", \"author\": { \"first_name\": \"Joe\", \"last_name\": \"Bloe\" }} ]\n```\n\n## Array Attributes\n\nYou can also extract attributes from array directly.\n\n```ruby\n# @people = People.all\n\njson.array! @people, :id, :name\n\n# => [ { \"id\": 1, \"name\": \"David\" }, { \"id\": 2, \"name\": \"Jamie\" } ]\n```\n\n## Plain Arrays\n\nTo make a plain array without keys, construct and pass in a standard Ruby array.\n\n```ruby\nmy_array = %w(David Jamie)\n\njson.people my_array\n\n# => \"people\": [ \"David\", \"Jamie\" ]\n```\n\n## Child Objects\n\nYou don't always have or need a collection when building an array.\n\n```ruby\njson.people do\n  json.child! do\n    json.id 1\n    json.name 'David'\n  end\n  json.child! do\n    json.id 2\n    json.name 'Jamie'\n  end\nend\n\n# => { \"people\": [ { \"id\": 1, \"name\": \"David\" }, { \"id\": 2, \"name\": \"Jamie\" } ] }\n```\n\n## Nested Jbuilder Objects\n\nJbuilder objects can be directly nested inside each other. Useful for composing objects.\n\n```ruby\nclass Person\n  # ... Class Definition ... #\n  def to_builder\n    Jbuilder.new do |person|\n      person.(self, :name, :age)\n    end\n  end\nend\n\nclass Company\n  # ... Class Definition ... #\n  def to_builder\n    Jbuilder.new do |company|\n      company.name name\n      company.president president.to_builder\n    end\n  end\nend\n\ncompany = Company.new('Doodle Corp', Person.new('John Stobs', 58))\ncompany.to_builder.target!\n\n# => {\"name\":\"Doodle Corp\",\"president\":{\"name\":\"John Stobs\",\"age\":58}}\n```\n\n## Rails Integration\n\nYou can either use Jbuilder stand-alone or directly as an ActionView template\nlanguage. When required in Rails, you can create views à la show.json.jbuilder\n(the json is already yielded):\n\n```ruby\n# Any helpers available to views are available to the builder\njson.content format_content(@message.content)\njson.(@message, :created_at, :updated_at)\n\njson.author do\n  json.name @message.creator.name.familiar\n  json.email_address @message.creator.email_address_with_name\n  json.url url_for(@message.creator, format: :json)\nend\n\nif current_user.admin?\n  json.visitors calculate_visitors(@message)\nend\n```\n\n## Partials\n\nYou can use partials as well. The following will render the file\n`views\u002Fcomments\u002F_comments.json.jbuilder`, and set a local variable\n`comments` with all this message's comments, which you can use inside\nthe partial.\n\n```ruby\njson.partial! 'comments\u002Fcomments', comments: @message.comments\n```\n\nIt's also possible to render collections of partials:\n\n```ruby\njson.array! @posts, partial: 'posts\u002Fpost', as: :post\n\n# or\njson.partial! 'posts\u002Fpost', collection: @posts, as: :post\n\n# or\njson.partial! partial: 'posts\u002Fpost', collection: @posts, as: :post\n\n# or\njson.comments @post.comments, partial: 'comments\u002Fcomment', as: :comment\n```\n\nThe `as: :some_symbol` is used with partials. It will take care of mapping the passed in object to a variable for the\npartial. If the value is a collection either implicitly or explicitly by using the `collection:` option, then each\nvalue of the collection is passed to the partial as the variable `some_symbol`. If the value is a singular object,\nthen the object is passed to the partial as the variable `some_symbol`.\n\nBe sure not to confuse the `as:` option to mean nesting of the partial. For example:\n\n```ruby\n# Use the default `views\u002Fcomments\u002F_comment.json.jbuilder`, putting @comment as the comment local variable.\n# Note, `comment` attributes are \"inlined\".\njson.partial! @comment, as: :comment\n```\n\nis quite different from:\n\n```ruby\n# comment attributes are nested under a \"comment\" property\njson.comment do\n  json.partial! \"\u002Fcomments\u002Fcomment.json.jbuilder\", comment: @comment\nend\n```\n\nYou can pass any objects into partial templates with or without `:locals` option.\n\n```ruby\njson.partial! 'sub_template', locals: { user: user }\n\n# or\n\njson.partial! 'sub_template', user: user\n```\n\n## Null Values\n\nYou can explicitly make Jbuilder object return null if you want:\n\n```ruby\njson.extract! @post, :id, :title, :content, :published_at\njson.author do\n  if @post.anonymous?\n    json.null! # or json.nil!\n  else\n    json.first_name @post.author_first_name\n    json.last_name @post.author_last_name\n  end\nend\n```\n\nTo prevent Jbuilder from including null values in the output, you can use the `ignore_nil!` method:\n\n```ruby\njson.ignore_nil!\njson.foo nil\njson.bar \"bar\"\n# => { \"bar\": \"bar\" }\n```\n\n## Caching\n\nFragment caching is supported, it uses `Rails.cache` and works like caching in\nHTML templates:\n\n```ruby\njson.cache! ['v1', @person], expires_in: 10.minutes do\n  json.extract! @person, :name, :age\nend\n```\n\nYou can also conditionally cache a block by using `cache_if!` like this:\n\n```ruby\njson.cache_if! !admin?, ['v1', @person], expires_in: 10.minutes do\n  json.extract! @person, :name, :age\nend\n```\n\nAside from that, the `:cached` options on collection rendering is available on Rails >= 6.0. This will cache the\nrendered results effectively using the multi fetch feature.\n\n```ruby\njson.array! @posts, partial: \"posts\u002Fpost\", as: :post, cached: true\n\n# or:\njson.comments @post.comments, partial: \"comments\u002Fcomment\", as: :comment, cached: true\n```\n\nIf 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:\n\n```ruby\njson.array! @posts, partial: \"posts\u002Fpost\", as: :post, cached: -> post { [post, current_user] }\n```\n\nThis will include both records as part of the cache key and updating either of them will expire the cache.\n\n## Formatting Keys\n\nKeys can be auto formatted using `key_format!`, this can be used to convert\nkeynames from the standard ruby_format to camelCase:\n\n```ruby\njson.key_format! camelize: :lower\njson.first_name 'David'\n\n# => { \"firstName\": \"David\" }\n```\n\nYou can set this globally with the class method `key_format` (from inside your\nenvironment.rb for example):\n\n```ruby\nJbuilder.key_format camelize: :lower\n```\n\nBy default, key format is not applied to keys of hashes that are\npassed to methods like `set!`, `array!` or `merge!`. You can opt into\ndeeply transforming these as well:\n\n```ruby\njson.key_format! camelize: :lower\njson.deep_format_keys!\njson.settings([{some_value: \"abc\"}])\n\n# => { \"settings\": [{ \"someValue\": \"abc\" }]}\n```\n\nYou can set this globally with the class method `deep_format_keys` (from inside your\nenvironment.rb for example):\n\n```ruby\nJbuilder.deep_format_keys true\n```\n\n## Testing JBuilder Response body with RSpec\n\nTo test the response body of your controller spec, enable `render_views` in your RSpec context. This [configuration](https:\u002F\u002Frspec.info\u002Ffeatures\u002F6-0\u002Frspec-rails\u002Fcontroller-specs\u002Frender-views) renders the views in a controller test.\n\n## Contributing to Jbuilder\n\nJbuilder is the work of many contributors. You're encouraged to submit pull requests, propose\nfeatures and discuss issues.\n\nSee [CONTRIBUTING](CONTRIBUTING.md).\n\n## License\n\nJbuilder is released under the [MIT License](http:\u002F\u002Fwww.opensource.org\u002Flicenses\u002FMIT).\n","Jbuilder 是一个用于生成 JSON 对象的 Ruby 库，它提供了一种 Builder 风格的领域特定语言（DSL），使得构建复杂的 JSON 结构变得更加直观和简洁。其核心功能包括支持条件判断、循环以及动态定义属性等特性，能够轻松处理包含大量逻辑判断的数据生成过程。此外，Jbuilder 还允许直接操作数组，并且可以将现有的哈希或数组合并到当前上下文中，非常适合在 Rails 应用中为 API 响应创建结构化的 JSON 输出。适用于需要频繁生成复杂 JSON 数据的 Web 开发场景，特别是那些基于 Rails 框架的应用程序。",2,"2026-06-11 03:14:14","top_language"]