class Jbuilder
Constants
- BLANK
- DependencyTracker
- NON_ENUMERABLES
Public Class Methods
Source
# File lib/jbuilder.rb, line 158 def self.deep_format_keys(value = true) @@deep_format_keys = value end
Same as instance method deep_format_keys
! except sets the default.
Source
# File lib/jbuilder.rb, line 26 def self.encode(*args, &block) new(*args, &block).target! end
Yields a builder and automatically turns the result into a JSON string
Source
# File lib/jbuilder.rb, line 133 def self.ignore_nil(value = true) @@ignore_nil = value end
Same as instance method ignore_nil
! except sets the default.
Source
# File lib/jbuilder.rb, line 109 def self.key_format(*args) @@key_formatter = KeyFormatter.new(*args) end
Same as the instance method key_format
! except sets the default.
Source
# File lib/jbuilder.rb, line 15 def initialize(options = {}) @attributes = {} @key_formatter = options.fetch(:key_formatter){ @@key_formatter ? @@key_formatter.clone : nil} @ignore_nil = options.fetch(:ignore_nil, @@ignore_nil) @deep_format_keys = options.fetch(:deep_format_keys, @@deep_format_keys) yield self if ::Kernel.block_given? end
Public Instance Methods
Source
# File lib/jbuilder.rb, line 213 def array!(collection = [], *attributes, &block) array = if collection.nil? [] elsif ::Kernel.block_given? _map_collection(collection, &block) elsif attributes.any? _map_collection(collection) { |element| extract! element, *attributes } else _format_keys(collection.to_a) end @attributes = _merge_values(@attributes, array) end
Turns the current element into an array and iterates over the passed collection, adding each iteration as an element of the resulting array.
Example:
json.array!(@people) do |person| json.name person.name json.age calculate_age(person.birthday) end [ { "name": David", "age": 32 }, { "name": Jamie", "age": 31 } ]
You can use the call syntax instead of an explicit extract! call:
json.(@people) { |person| ... }
It’s generally only needed to use this method for top-level arrays. If you have named arrays, you can do:
json.people(@people) do |person| json.name person.name json.age calculate_age(person.birthday) end { "people": [ { "name": David", "age": 32 }, { "name": Jamie", "age": 31 } ] }
If you omit the block then you can set the top level array directly:
json.array! [1, 2, 3] [1,2,3]
Source
# File lib/jbuilder.rb, line 268 def attributes! @attributes end
Returns the attributes of the current builder.
Source
# File lib/jbuilder.rb, line 252 def call(object, *attributes, &block) if ::Kernel.block_given? array! object, &block else extract! object, *attributes end end
Source
# File lib/jbuilder.rb, line 178 def child! @attributes = [] unless ::Array === @attributes @attributes << _scope{ yield self } end
Turns the current element into an array and yields a builder to add a hash.
Example:
json.comments do json.child! { json.content "hello" } json.child! { json.content "world" } end { "comments": [ { "content": "hello" }, { "content": "world" } ]}
More commonly, you’d use the combined iterator, though:
json.comments(@post.comments) do |comment| json.content comment.formatted_content end
Source
# File lib/jbuilder.rb, line 153 def deep_format_keys!(value = true) @deep_format_keys = value end
Deeply apply key format to nested hashes and arrays passed to methods like set!, merge! or array!.
Example:
json.key_format! camelize: :lower json.settings({some_value: "abc"}) { "settings": { "some_value": "abc" }} json.key_format! camelize: :lower json.deep_format_keys! json.settings({some_value: "abc"}) { "settings": { "someValue": "abc" }}
Source
# File lib/jbuilder.rb, line 244 def extract!(object, *attributes) if ::Hash === object _extract_hash_values(object, attributes) else _extract_method_values(object, attributes) end end
Extracts the mentioned attributes or hash elements from the passed object and turns them into attributes of the JSON.
Example:
@person = Struct.new(:name, :age).new('David', 32) or you can utilize a Hash @person = { name: 'David', age: 32 } json.extract! @person, :name, :age { "name": David", "age": 32 }, { "name": Jamie", "age": 31 }
You can also use the call syntax instead of an explicit extract! call:
json.(@person, :name, :age)
Source
# File lib/jbuilder.rb, line 128 def ignore_nil!(value = true) @ignore_nil = value end
If you want to skip adding nil values to your JSON hash. This is useful for JSON clients that don’t deal well with nil values, and would prefer not to receive keys which have null values.
Example:
json.ignore_nil! false json.id User.new.id { "id": null } json.ignore_nil! json.id User.new.id {}
Source
# File lib/jbuilder.rb, line 104 def key_format!(*args) @key_formatter = KeyFormatter.new(*args) end
Specifies formatting to be applied to the key. Passing in a name of a function will cause that function to be called on the key. So :upcase will upper case the key. You can also pass in lambdas for more complex transformations.
Example:
json.key_format! :upcase json.author do json.name "David" json.age 32 end { "AUTHOR": { "NAME": "David", "AGE": 32 } }
You can pass parameters to the method using a hash pair.
json.key_format! camelize: :lower json.first_name "David" { "firstName": "David" }
Lambdas can also be used.
json.key_format! ->(key){ "_" + key } json.first_name "David" { "_first_name": "David" }
Source
# File lib/jbuilder.rb, line 273 def merge!(object) hash_or_array = ::Jbuilder === object ? object.attributes! : object @attributes = _merge_values(@attributes, _format_keys(hash_or_array)) end
Merges hash, array, or Jbuilder
instance into current builder.
Source
# File lib/jbuilder.rb, line 68 def method_missing(*args, &block) if ::Kernel.block_given? set!(*args, &block) else set!(*args) end end
Source
# File lib/jbuilder.rb, line 261 def nil! @attributes = nil end
Returns the nil JSON.
Source
# File lib/jbuilder.rb, line 33 def set!(key, value = BLANK, *args, &block) result = if ::Kernel.block_given? if !_blank?(value) # json.comments @post.comments { |comment| ... } # { "comments": [ { ... }, { ... } ] } _scope{ array! value, &block } else # json.comments { ... } # { "comments": ... } _merge_block(key){ yield self } end elsif args.empty? if ::Jbuilder === value # json.age 32 # json.person another_jbuilder # { "age": 32, "person": { ... } _format_keys(value.attributes!) else # json.age 32 # { "age": 32 } _format_keys(value) end elsif _is_collection?(value) # json.comments @post.comments, :content, :created_at # { "comments": [ { "content": "hello", "created_at": "..." }, { "content": "world", "created_at": "..." } ] } _scope{ array! value, *args } else # json.author @post.creator, :name, :email_address # { "author": { "name": "David", "email_address": "david@loudthinking.com" } } _merge_block(key){ extract! value, *args } end _set_value key, result end
Source
# File lib/jbuilder.rb, line 279 def target! @attributes.to_json end
Encodes the current builder as JSON.
Private Instance Methods
Source
# File lib/jbuilder.rb, line 357 def _blank?(value=@attributes) BLANK == value end
Source
# File lib/jbuilder.rb, line 285 def _extract_hash_values(object, attributes) attributes.each{ |key| _set_value key, _format_keys(object.fetch(key)) } end
Source
# File lib/jbuilder.rb, line 289 def _extract_method_values(object, attributes) attributes.each{ |key| _set_value key, _format_keys(object.public_send(key)) } end
Source
# File lib/jbuilder.rb, line 318 def _format_keys(hash_or_array) return hash_or_array unless @deep_format_keys if ::Array === hash_or_array hash_or_array.map { |value| _format_keys(value) } elsif ::Hash === hash_or_array ::Hash[hash_or_array.collect { |k, v| [_key(k), _format_keys(v)] }] else hash_or_array end end
Source
# File lib/jbuilder.rb, line 353 def _is_collection?(object) _object_respond_to?(object, :map, :count) && NON_ENUMERABLES.none?{ |klass| klass === object } end
Source
# File lib/jbuilder.rb, line 314 def _key(key) @key_formatter ? @key_formatter.format(key) : key.to_s end
Source
# File lib/jbuilder.rb, line 338 def _map_collection(collection) collection.map do |element| _scope{ yield element } end - [BLANK] end
Source
# File lib/jbuilder.rb, line 293 def _merge_block(key) current_value = _blank? ? BLANK : @attributes.fetch(_key(key), BLANK) raise NullError.build(key) if current_value.nil? new_value = _scope{ yield self } _merge_values(current_value, new_value) end
Source
# File lib/jbuilder.rb, line 300 def _merge_values(current_value, updates) if _blank?(updates) current_value elsif _blank?(current_value) || updates.nil? || current_value.empty? && ::Array === updates updates elsif ::Array === current_value && ::Array === updates current_value + updates elsif ::Hash === current_value && ::Hash === updates current_value.deep_merge(updates) else raise MergeError.build(current_value, updates) end end
Source
# File lib/jbuilder.rb, line 361 def _object_respond_to?(object, *methods) methods.all?{ |m| object.respond_to?(m) } end
Source
# File lib/jbuilder.rb, line 344 def _scope parent_attributes, parent_formatter, parent_deep_format_keys = @attributes, @key_formatter, @deep_format_keys @attributes = BLANK yield @attributes ensure @attributes, @key_formatter, @deep_format_keys = parent_attributes, parent_formatter, parent_deep_format_keys end
Source
# File lib/jbuilder.rb, line 330 def _set_value(key, value) raise NullError.build(key) if @attributes.nil? raise ArrayError.build(key) if ::Array === @attributes return if @ignore_nil && value.nil? or _blank?(value) @attributes = {} if _blank? @attributes[_key(key)] = value end