-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move code into Deserialization module. Add support for whitelisting.
- Loading branch information
Showing
3 changed files
with
129 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
lib/active_model/serializer/adapter/json_api/deserialization.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
module ActiveModel | ||
class Serializer | ||
module Adapter | ||
class JsonApi | ||
module Deserialization | ||
module_function | ||
|
||
# Parse a Hash or ActionController::Parameters representing a JSON API document | ||
# into an ActiveRecord-ready hash. | ||
# | ||
# @param [Hash|ActionController::Parameters] document | ||
# @param [Hash] options | ||
# fields: Array of symbols and a Hash. Specify whitelisted fields, optionally | ||
# specifying the attribute name on the model. | ||
# @return [Hash] ActiveRecord-ready hash | ||
# | ||
def parse(document, options = {}) | ||
fields = parse_fields(options[:fields]) | ||
|
||
hash = {} | ||
|
||
primary_data = document.fetch('data', {}) | ||
hash[:id] = primary_data['id'] if primary_data['id'] | ||
|
||
hash.merge!(parse_attributes(primary_data['attributes'], fields)) | ||
hash.merge!(parse_relationships(primary_data['relationships'], fields)) | ||
|
||
hash | ||
end | ||
|
||
# @api private | ||
def parse_fields(fields) | ||
return nil unless fields.is_a?(Array) | ||
fields.each_with_object({}) do |attr, hash| | ||
if attr.is_a?(Symbol) | ||
hash[attr] = attr | ||
elsif attr.is_a?(Hash) | ||
hash.merge!(attr) | ||
end | ||
end | ||
end | ||
|
||
# @api private | ||
def parse_attributes(attributes, fields) | ||
return {} unless attributes | ||
attributes.each_with_object({}) do |(key, value), hash| | ||
attribute_name = fields ? fields[key.to_sym] : key.to_sym | ||
next unless attribute_name | ||
hash[attribute_name] = value | ||
end | ||
end | ||
|
||
# @api private | ||
def parse_relationships(relationships, fields) | ||
return {} unless relationships | ||
relationships.each_with_object({}) do |(key, value), hash| | ||
association_name = fields ? fields[key.to_sym] : key.to_sym | ||
next unless association_name | ||
data = value['data'] | ||
if data.is_a?(Array) | ||
key = "#{association_name.to_s.singularize.to_sym}_ids".to_sym | ||
hash[key] = data.map { |ri| ri['id'] } | ||
else | ||
key = "#{association_name}_id".to_sym | ||
hash[key] = data ? data['id'] : nil | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters