Skip to content

Instantly share code, notes, and snippets.

@vinchi777
Created August 27, 2021 12:14
Show Gist options
  • Save vinchi777/7b8b121507efd8844054f6001e0d92ef to your computer and use it in GitHub Desktop.
Save vinchi777/7b8b121507efd8844054f6001e0d92ef to your computer and use it in GitHub Desktop.
Nested attribute normalizer
# Converts
# This
# {
# attributes: {
# name: 'jude',
# address.street: 'main street',
# address.city: 'cebu'
# },
# relationships: { checkout: { data: { id: 2, type: 'checkouts' } } }
# }
#
#
# To this
# {:name=>"jude", :address_attributes=>{:street=>"main street", :city=>"cebu"}, :checkout_id=>2}
module JsonApiSpecParamNormalizer
class << self
def normalize(resource_permitted_params)
hash = {}
hash.merge!(direct_attributes(resource_permitted_params))
hash.merge!(nested_attributes(resource_permitted_params))
hash.merge!(foreign_key_attributes(resource_permitted_params))
hash.to_h.deep_symbolize_keys
end
def direct_attributes(params)
params.dig(:attributes).select{ |key, _val| !key.to_s.include?('.') } || {}
end
def nested_attributes(params)
params.dig(:attributes).select{ |key, _val| key.to_s.include?('.') }.keys.each_with_object({}) do |key, hash|
relation, attribute = key.to_s.split('.')
hash["#{relation}_attributes"] ||= {}
hash["#{relation}_attributes"][attribute] = params.dig(:attributes, key)
end
end
def foreign_key_attributes(params)
(params.dig(:relationships) || {}).keys.each_with_object({}) do |relation, hash|
relation_data = params.dig(:relationships, relation)
if !relation_data.is_a?(Array)
hash["#{relation}_id".to_sym] = params.dig(:relationships, relation, :data, :id)
end
end
end
end
end
# Usage
params = {
attributes: {
name: 'jude',
'address.street': 'main street',
'address.city': 'cebu'
},
relationships: { checkout: { data: { id: 2, type: 'checkouts' } } }
}
puts JsonApiSpecParamNormalizer.normalize(params)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment