module Sequel::Plugins::JsonSerializer::InstanceMethods

Public Instance Methods

from_json(json, opts=OPTS) click to toggle source

Parse the provided JSON, which should return a hash, and process the hash with from_json_node.

# File lib/sequel/plugins/json_serializer.rb, line 202
def from_json(json, opts=OPTS)
  from_json_node(Sequel.parse_json(json), opts)
end
from_json_node(hash, opts=OPTS) click to toggle source

Using the provided hash, update the instance with data contained in the hash. By default, just calls set with the hash values.

Options:

:associations

Indicates that the associations cache should be updated by creating a new associated object using data from the hash. Should be a Symbol for a single association, an array of symbols for multiple associations, or a hash with symbol keys and dependent association option hash values.

:fields

Changes the behavior to call set_fields using the provided fields, instead of calling set.

# File lib/sequel/plugins/json_serializer.rb, line 215
def from_json_node(hash, opts=OPTS)
  unless hash.is_a?(Hash)
    raise Error, "parsed json doesn't return a hash"
  end

  populate_associations = {}

  if assocs = opts[:associations]
    assocs = case assocs
    when Symbol
      {assocs=>{}}
    when Array
      assocs_tmp = {}
      assocs.each{|v| assocs_tmp[v] = {}}
      assocs_tmp
    when Hash
      assocs
    else
      raise Error, ":associations should be Symbol, Array, or Hash if present"
    end

    assocs.each do |assoc, assoc_opts|
      if assoc_values = hash.delete(assoc.to_s)
        unless r = model.association_reflection(assoc)
          raise Error, "Association #{assoc} is not defined for #{model}"
        end

        populate_associations[assoc] = if r.returns_array?
          raise Error, "Attempt to populate array association with a non-array" unless assoc_values.is_a?(Array)
          assoc_values.map{|v| v.is_a?(r.associated_class) ? v : r.associated_class.new.from_json_node(v, assoc_opts)}
        else
          raise Error, "Attempt to populate non-array association with an array" if assoc_values.is_a?(Array)
          assoc_values.is_a?(r.associated_class) ? assoc_values : r.associated_class.new.from_json_node(assoc_values, assoc_opts)
        end
      end
    end
  end

  if fields = opts[:fields]
    set_fields(hash, fields, opts)
  else
    set(hash)
  end

  populate_associations.each do |assoc, values|
    associations[assoc] = values
  end

  self
end
json_serializer_opts(opts=OPTS) click to toggle source

Set the json serialization options that will be used by default in future calls to to_json. This is designed for cases where the model object will be used inside another data structure which #to_json is called on, and as such will not allow passing of arguments to to_json.

Example:

obj.json_serializer_opts(:only=>:name)
[obj].to_json # => '[{"name":"..."}]'
# File lib/sequel/plugins/json_serializer.rb, line 276
def json_serializer_opts(opts=OPTS)
  @json_serializer_opts = Hash[@json_serializer_opts||OPTS].merge!(opts)
end
to_json(*a) click to toggle source

Return a string in JSON format. Accepts the following options:

:except

Symbol or Array of Symbols of columns not to include in the JSON output.

:include

Symbol, Array of Symbols, or a Hash with Symbol keys and Hash values specifying associations or other non-column attributes to include in the JSON output. Using a nested hash, you can pass options to associations to affect the JSON used for associated objects.

:only

Symbol or Array of Symbols of columns to only include in the JSON output, ignoring all other columns.

:root

Qualify the JSON with the name of the object. If a string is given, use the string as the key, otherwise use an underscored version of the model's name.

# File lib/sequel/plugins/json_serializer.rb, line 297
def to_json(*a)
  opts = model.json_serializer_opts
  opts = Hash[opts].merge!(@json_serializer_opts) if @json_serializer_opts
  if (arg_opts = a.first).is_a?(Hash)
    opts = Hash[opts].merge!(arg_opts)
    a = []
  end

  vals = values
  cols = if only = opts[:only]
    Array(only)
  else
    vals.keys - Array(opts[:except])
  end

  h = {}

  cols.each{|c| h[c.to_s] = get_column_value(c)}
  if inc = opts[:include]
    if inc.is_a?(Hash)
      inc.each do |k, v|
        if k.is_a?(Sequel::SQL::AliasedExpression)
          key_name = k.aliaz.to_s
          k = k.expression
        else
          key_name = k.to_s
        end

        v = v.empty? ? [] : [v]

        objs = send(k)

        is_array = if r = model.association_reflection(k)
          r.returns_array?
        else
          objs.is_a?(Array)
        end
        
        h[key_name] = if is_array
          objs.map{|obj| Literal.new(Sequel.object_to_json(obj, *v))}
        else
          Literal.new(Sequel.object_to_json(objs, *v))
        end
      end
    else
      Array(inc).each do |c|
        if c.is_a?(Sequel::SQL::AliasedExpression)
          key_name = c.aliaz.to_s
          c = c.expression
        else
          key_name = c.to_s
        end
        h[key_name] = send(c)
      end
    end
  end

  if root = opts[:root]
    unless root.is_a?(String)
      root = model.send(:underscore, model.send(:demodulize, model.to_s))
    end
    h = {root => h}
  end

  Sequel.object_to_json(h, *a)
end