Class: JsonApiable::ParamsParser

Inherits:
Object
  • Object
show all
Defined in:
lib/json_apiable/params_parser.rb

Defined Under Namespace

Classes: DataParams

Class Method Summary collapse

Class Method Details

.build_attributes_hash(attributes, excluded_attributes) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/json_apiable/params_parser.rb', line 32

def self.build_attributes_hash(attributes, excluded_attributes)
  attrs_hash = {}
  attributes&.each do |key, value|
    next if excluded_attributes&.include?(key.to_sym)

    new_key = nested_attributes?(value) ? "#{key}_attributes" : key
    attrs_hash[new_key] = value.is_a?(ActionController::Parameters) ? value.to_h : value
  end
  attrs_hash
end

.build_relationship_attribute_hash(data_hash) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/json_apiable/params_parser.rb', line 69

def self.build_relationship_attribute_hash(data_hash)
  attr_hash = {}
  data_hash['data'].each_with_index do |arr_item, i|
    item_hash = { 'id' => arr_item['id'], '_destroy' => 'false' }
    attr_hash[i.to_s] = item_hash
  end
  attr_hash
end

.build_relationships_hash(relationships, excluded_relationships, request) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/json_apiable/params_parser.rb', line 43

def self.build_relationships_hash(relationships, excluded_relationships, request)
  attr_hash = {}
  ids_array = []
  ids_key = nil

  relationships&.each_pair do |key, data_hash|
    next if excluded_relationships&.include?(key.to_sym)

    if ActiveSupport::Inflector.pluralize(key) == key
      new_key = "#{key}_attributes"
      new_value = build_relationship_attribute_hash(data_hash)
      ids_key = "#{ActiveSupport::Inflector.singularize(key)}_ids"
      ids_array = data_hash['data']&.map { |h| h['id'] }
    else
      new_key = "#{key}_id"
      new_value = data_hash['data']['id']
    end
    attr_hash[new_key] = new_value
    # ids array is needed when creating a new AR object which accepts_nested_attributes for existing AR object(s)
    # as in the case of a new Message which accepts existing attachments
    # https://stackoverflow.com/a/25943832/1983833
    attr_hash[ids_key] = ids_array if ids_array.present? && (request.post? || request.patch?)
  end
  attr_hash
end

.hashify(allowed_relationships) ⇒ Object



78
79
80
# File 'lib/json_apiable/params_parser.rb', line 78

def self.hashify(allowed_relationships)
  allowed_relationships.map { |rel| { rel => {} } }
end

.nested_attributes?(value) ⇒ Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/json_apiable/params_parser.rb', line 82

def self.nested_attributes?(value)
  value.is_a?(ActionController::Parameters) || value.is_a?(Array)
end

.parse_body_params(request, params, allowed_attributes, excluded_attributes, allowed_relationships, excluded_relationships) ⇒ Object

Convert JsonAPI request body into Rails params hash



14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/json_apiable/params_parser.rb', line 14

def self.parse_body_params(request, params, allowed_attributes, excluded_attributes,
                           allowed_relationships, excluded_relationships)
  permitted_params = validate_data_params!(params,
                                           allowed_attributes,
                                           hashify(allowed_relationships))
  attributes_hash = build_attributes_hash(permitted_params.dig(:attributes), excluded_attributes)
  relationships_hash = build_relationships_hash(permitted_params.dig(:relationships), excluded_relationships, request)
  attributes_hash.merge(relationships_hash)
rescue ArgumentError, ActionController::UnpermittedParameters
  raise
rescue StandardError => e
  raise Errors::MalformedRequestError, e.message
end

.validate_data_params!(params, attributes, relationships) ⇒ Object



28
29
30
# File 'lib/json_apiable/params_parser.rb', line 28

def self.validate_data_params!(params, attributes, relationships)
  DataParams.build(params, attributes, relationships)
end