|
| 1 | +require 'jsonapi/parser' |
| 2 | +require 'jsonapi/parser/bulk' |
| 3 | +require 'jsonapi/rails/deserializable_resource' |
| 4 | +require 'jsonapi/rails/controller/deserialization' |
| 5 | + |
| 6 | +module JSONAPI |
| 7 | + module Rails |
| 8 | + module Controller |
| 9 | + module BulkDeserialization |
| 10 | + extend ActiveSupport::Concern |
| 11 | + |
| 12 | + class_methods do |
| 13 | + def deserializable_resource(key, options = {}, &block) |
| 14 | + options = options.dup |
| 15 | + klass = options.delete(:class) || |
| 16 | + Class.new(JSONAPI::Rails::DeserializableResource, &block) |
| 17 | + bulk = options.delete(:bulk) || false |
| 18 | + |
| 19 | + before_action(options) do |controller| |
| 20 | + hash = controller.params.to_unsafe_hash.with_indifferent_access[:_jsonapi] |
| 21 | + if hash.nil? |
| 22 | + JSONAPI::Rails.logger.warn do |
| 23 | + "Unable to deserialize #{key} because no JSON API payload was" \ |
| 24 | + " found. (#{controller.controller_name}##{params[:action]})" |
| 25 | + end |
| 26 | + next |
| 27 | + end |
| 28 | + |
| 29 | + ActiveSupport::Notifications |
| 30 | + .instrument('parse.jsonapi-rails', |
| 31 | + key: key, payload: hash, class: klass) do |
| 32 | + if bulk && controller.request.headers['Content-Type'] =~ /;\s?ext=bulk\b/ |
| 33 | + JSONAPI::Parser::Bulk.parse!(hash) |
| 34 | + resources = hash[:data].map { |data| klass.new(data) } |
| 35 | + controller.request.env[JSONAPI::Rails::Controller::Deserialization::JSONAPI_POINTERS_KEY] = resources.first.reverse_mapping |
| 36 | + controller.params[key.to_sym] = resources.map(&:to_hash) |
| 37 | + else |
| 38 | + JSONAPI::Parser::Resource.parse!(hash) |
| 39 | + resource = klass.new(hash[:data]) |
| 40 | + controller.request.env[JSONAPI::Rails::Controller::Deserialization::JSONAPI_POINTERS_KEY] = resource.reverse_mapping |
| 41 | + controller.params[key.to_sym] = resource.to_hash |
| 42 | + end |
| 43 | + end |
| 44 | + end |
| 45 | + end |
| 46 | + end |
| 47 | + end |
| 48 | + end |
| 49 | + end |
| 50 | +end |
0 commit comments