class Jbuilder - jbuilder-1.5.3 Documentation

# class Jbuilder

### Constants

BLANK

### Public Class Methods

encode(*args, &block) click to toggle source

Yields a builder and automatically turns the result into a JSON string

    # File lib/jbuilder.rb, line 54
    def self.encode(*args, &block)
      new(*args, &block).target!
    end

ignore_nil(value = true) click to toggle source

Same as instance method ::ignore_nil! except sets the default.

    # File lib/jbuilder.rb, line 169
    def self.ignore_nil(value = true)
      @@ignore_nil = value
    end

key_format(*args) click to toggle source

Same as the instance method ::key_format! except sets the default.

    # File lib/jbuilder.rb, line 145
    def self.key_format(*args)
      @@key_formatter = KeyFormatter.new(*args)
    end

new(*args) { |self| ... } click to toggle source

    # File lib/jbuilder.rb, line 61
    def initialize(*args, &block)
      @attributes = ::ActiveSupport::OrderedHash.new

      options = args.extract_options!
      @key_formatter = options.fetch(:key_formatter){ @@key_formatter.clone }
      @ignore_nil = options.fetch(:ignore_nil, @@ignore_nil)
      yield self if block
    end

### Public Instance Methods

array!(collection = [], *attributes, &block) click to toggle source

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

If you are using Ruby 1.9+, 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]

    # File lib/jbuilder.rb, line 224
    def array!(collection = [], *attributes, &block)
      @attributes = if block && block.arity == 2
        _two_arguments_map_collection(collection, &block)
      elsif block
        _map_collection(collection, &block)
      elsif attributes.any?
        _map_collection(collection) { |element| extract! element, *attributes }
      else
        collection
      end
    end

attributes!() click to toggle source

Returns the attributes of the current builder.

    # File lib/jbuilder.rb, line 277
    def attributes!
      @attributes
    end

call(object, *attributes, &block) click to toggle source

    # File lib/jbuilder.rb, line 261
    def call(object, *attributes, &block)
      if block
        array! object, &block
      else
        extract! object, *attributes
      end
    end

child!() { |self| ... } click to toggle source

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

    # File lib/jbuilder.rb, line 189
    def child!
      @attributes = [] unless ::Array === @attributes
      @attributes << _scope { yield self }
    end

extract!(object, *attributes) click to toggle source

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)

    # File lib/jbuilder.rb, line 253
    def extract!(object, *attributes)
      if ::Hash === object
        _extract_hash_values(object, *attributes)
      else
        _extract_method_values(object, *attributes)
      end
    end

ignore_nil!(value = true) click to toggle source

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

    {}

    # File lib/jbuilder.rb, line 164
    def ignore_nil!(value = true)
      @ignore_nil = value
    end

key_format!(*args) click to toggle source

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

    # File lib/jbuilder.rb, line 140
    def key_format!(*args)
      @key_formatter = KeyFormatter.new(*args)
    end

nil!() click to toggle source

Returns the nil JSON.

    # File lib/jbuilder.rb, line 270
    def nil!
      @attributes = nil
    end

Also aliased as: null!
null!()
Alias for: nil!
set!(key, value = BLANK, *args) { |self| ... } click to toggle source

    # File lib/jbuilder.rb, line 72
    def set!(key, value = BLANK, *args, &block)

      result = if block
        if BLANK != value
          # json.comments @post.comments { |comment| ... }
          # { "comments": [ { ... }, { ... } ] }
          _scope{ array! value, &block }
        else
          # json.comments { ... }
          # { "comments": ... }
          _scope { yield self }
        end
      elsif args.empty?
        if ::Jbuilder === value
          # json.age 32
          # json.person another_jbuilder
          # { "age": 32, "person": { ...  }
          value.attributes!
        else
          # json.age 32
          # { "age": 32 }
          value
        end
      elsif _mapable_arguments?(value, *args)
        # 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" } }
        _scope { extract! value, *args }
      end

      _set_value key, result
    end

Also aliased as: method_missing
target!() click to toggle source

Encodes the current builder as JSON.

    # File lib/jbuilder.rb, line 282
    def target!
      ::MultiJson.dump @attributes
    end

### Private Instance Methods

_extract_hash_values(object, *attributes) click to toggle source

    # File lib/jbuilder.rb, line 288
    def  _extract_hash_values(object, *attributes)
      attributes.each{ |key| _set_value key, object.fetch(key) }
    end

_extract_method_values(object, *attributes) click to toggle source

    # File lib/jbuilder.rb, line 292
    def _extract_method_values(object, *attributes)
      attributes.each do |method_name|
        unless object.respond_to?(method_name)
          message = "Private method #{method_name.inspect} was used to " +
            'extract value. This will be an error in future versions of Jbuilder'
        end

        _set_value method_name, object.send(method_name)
        ::ActiveSupport::Deprecation.warn message if message
      end
    end

_map_collection(collection) { |element| ... } click to toggle source

    # File lib/jbuilder.rb, line 311
    def _map_collection(collection)
      return [] if collection.nil?

      collection.map do |element|
        _scope { yield element }
      end
    end

_mapable_arguments?(value, *args) click to toggle source

    # File lib/jbuilder.rb, line 353
    def _mapable_arguments?(value, *args)
      value.respond_to?(:map)
    end

_merge(hash_or_array) click to toggle source

    # File lib/jbuilder.rb, line 328
    def _merge(hash_or_array)
      if ::Array === hash_or_array
        @attributes = [] unless ::Array === @attributes
        @attributes.concat hash_or_array
      else
        @attributes.update hash_or_array
      end
    end

_scope() { || ... } click to toggle source

    # File lib/jbuilder.rb, line 319
    def _scope
      parent_attributes, parent_formatter = @attributes, @key_formatter
      @attributes = ::ActiveSupport::OrderedHash.new
      yield
      @attributes
    ensure
      @attributes, @key_formatter = parent_attributes, parent_formatter
    end

_set_value(key, value) click to toggle source

    # File lib/jbuilder.rb, line 304
    def _set_value(key, value)
      raise NullError, key if @attributes.nil?
      unless @ignore_nil && value.nil?
        @attributes[@key_formatter.format(key)] = value
      end
    end

_two_arguments_map_collection(collection, &block) click to toggle source

    # File lib/jbuilder.rb, line 337
    def _two_arguments_map_collection(collection, &block)
      message = "Passing jbuilder object to block is "          "deprecated and will be removed soon."

      if block.respond_to?(:parameters)
        arguments  = block.parameters.map(&:last)
        actual     = "|#{arguments.drop(1) * ', '}|"
        deprecated = "|#{arguments * ', '}|"
        message   += "\nUse #{actual} instead of #{deprecated} as block arguments"
      end

      ::ActiveSupport::Deprecation.warn message, ::Kernel.caller(5)

      _map_collection(collection){ |element| block[self, element] }
    end

method_missing(key, value = BLANK, *args, &block)
Alias for: set!