Class: Onsi::Params

Inherits:
Object
  • Object
show all
Defined in:
lib/onsi/params.rb

Overview

Used to handle parsing JSON-API formated params

Examples:

class PeopleController < ApplicationController
  include Onsi::Controller

  def create
    attributes = Onsi::Param.parse(
      params,
      [:first_name, :last_name],
      [:team]
    )
    render_resource Person.create!(attributes.flatten)
  end
end

Defined Under Namespace

Classes: MissingReqiredAttribute, RelationshipNotFound

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#attributesActionController::Parameters (readonly)

The attributes for the params.

Returns:

  • (ActionController::Parameters)


106
107
108
# File 'lib/onsi/params.rb', line 106

def attributes
  @attributes
end

#relationshipsHash (readonly)

The relationships for the params.

Returns:

  • (Hash)


112
113
114
# File 'lib/onsi/params.rb', line 112

def relationships
  @relationships
end

Class Method Details

.parse(params, attributes = [], relationships = []) ⇒ Params

Parse a JSON-API formatted params object.

Parameters:

  • params (ActionController::Parameters)

    The parameters to parse.

  • attributes (Array<String, Symbol>) (defaults to: [])

    The whitelisted attributes.

  • relationships (Array<String, Symbol>) (defaults to: [])

    The whitelisted relationships. Should be the key for the relationships name.

Returns:

  • (Params)

    The new params object.



74
75
76
77
78
79
80
81
# File 'lib/onsi/params.rb', line 74

def parse(params, attributes = [], relationships = [])
  parser = Onsi::ParamsParser.new(params, attributes, relationships)
  results = parser.parse!
  new(
    results.attributes,
    results.relationships
  )
end

.parse_json(body, attributes = [], relationships = []) ⇒ Onsi::Params

Parse a JSON-API formatted JSON object.

Parameters:

  • body (String, #read)

    The parameters to parse.

  • attributes (Array<String, Symbol>) (defaults to: [])

    The whitelisted attributes.

  • relationships (Array<String, Symbol>) (defaults to: [])

    The whitelisted relationships. Should be the key for the relationships name.

Returns:



94
95
96
97
98
99
# File 'lib/onsi/params.rb', line 94

def parse_json(body, attributes = [], relationships = [])
  content = body.respond_to?(:read) ? body.read : body
  json = JSON.parse(content)
  params = ActionController::Parameters.new(json)
  parse(params, attributes, relationships)
end

Instance Method Details

#default(key, value) ⇒ Object

Set a default value for attributes.

This value will only be used if the key is missing from the passed attributes

Examples:

params.default(:missing, -> { :foo })
subject.flatten[:missing]
# => :foo

Parameters:

  • key (String, Symbol)

    The key to set a default on.

  • value (Any, #call)

    The default value. If the object responds to call (Lambda) it will be called when parsing attributes



230
231
232
233
# File 'lib/onsi/params.rb', line 230

def default(key, value)
  @attrs_hash = nil
  defaults[key.to_sym] = value
end

#fetch(key, default = nil) ⇒ Any

Fetch a value from the attributes or return the passed default value

Parameters:

  • key (String, Symbol)

    The key to fetch.

  • default (Any) (defaults to: nil)

    The default value if the attribute doesn’t exist.

Returns:

  • (Any)


145
146
147
# File 'lib/onsi/params.rb', line 145

def fetch(key, default = nil)
  attrs_hash[key] || default
end

#flattenHash

Flatten an merge the attributes & relationships into one hash.

Returns:

  • (Hash)

    The flattened attributes and relationships



133
134
135
# File 'lib/onsi/params.rb', line 133

def flatten
  @flattened ||= attrs_hash.to_h.merge(relationships.to_h).with_indifferent_access
end

#require(key) ⇒ Any

Make an attributes key required.

Parameters:

  • key (String, Symbol)

    The key of the attribute to require.

Returns:

  • (Any)

    The value for the attribute

Raises:



157
158
159
160
161
162
163
164
# File 'lib/onsi/params.rb', line 157

def require(key)
  value = attrs_hash[key]
  if value.nil?
    raise MissingReqiredAttribute.new("Missing attribute #{key}", key)
  end

  value
end

#require_path(key_path) ⇒ Object



166
167
168
169
170
171
172
173
# File 'lib/onsi/params.rb', line 166

def require_path(key_path)
  value = flatten.dig(*key_path.split('/'))
  if value.nil?
    raise MissingReqiredAttribute.new("Missing attribute at key_path #{key_path}", key_path)
  end

  value
end

#safe_fetch(key) ⇒ Any

Handle finding a relationship’s object.

Examples:

params.safe_fetch(:person) do |id|
  Person.find(id)
end

Parameters:

  • key (String, Symbol)

    The key for the relationship

Returns:

  • (Any)

Raises:

  • (RelationshipNotFound)

    Thrown instead of an ‘ActiveRecord::RecordNotFound` This allows the `Onsi::ErrorResponder` to build an appropriate response.



189
190
191
192
193
# File 'lib/onsi/params.rb', line 189

def safe_fetch(key)
  yield(@relationships[key])
rescue ActiveRecord::RecordNotFound
  raise RelationshipNotFound.new("Can't find relationship #{key}", key)
end

#transform(key, &block) ⇒ Any

Note:

The values are memoized

Perform a transform on the value

Any getter will run the value through the transform block.

Examples:

params.transform(:date) { |date| Time.parse(date) }

Parameters:

  • key (String, Symbol)

    The key to transform.

  • block (Block)

    The block to perform the transform.

Returns:

  • (Any)


210
211
212
213
# File 'lib/onsi/params.rb', line 210

def transform(key, &block)
  @attrs_hash = nil
  transforms[key.to_sym] = block
end