Skip to content

Commit 2a37286

Browse files
authored
Fix deserialization. (#1)
1 parent 1484f93 commit 2a37286

File tree

2 files changed

+36
-26
lines changed

2 files changed

+36
-26
lines changed

lib/jsonapi/rails/action_controller.rb

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,54 +7,63 @@ module ActionController
77
def self.included(base)
88
base.class_eval do
99
extend ClassMethods
10-
prepend InstanceMethods
1110
end
1211
end
1312

1413
module ClassMethods
15-
def deserializable_resource(key, klass = nil, &block)
14+
def deserializable_resource(key, *args, &block)
15+
klass = args.shift unless args.first.is_a?(Hash)
16+
options = args.first || {}
1617
if klass.nil?
1718
klass = Class.new(JSONAPI::Deserializable::Resource, &block)
1819
end
19-
@deserializable_key = key
20-
@deserializable_class = klass
21-
@deserializable_parser = JSONAPI::Parser::Resource
20+
use DeserializeResource, key, klass, options
2221
end
2322

24-
def deserializable_relationship(key, klass = nil, &block)
23+
def deserializable_relationship(key, *args, &block)
24+
klass = args.shift unless args.first.is_a?(Hash)
25+
options = args.first || {}
2526
if klass.nil?
2627
klass = Class.new(JSONAPI::Deserializable::Relationship, &block)
2728
end
29+
use DeserializeResource, key, klass, options
30+
end
31+
end
32+
33+
class DeserializationMiddleware
34+
JSONAPI_KEYS = %w(data meta links jsonapi).freeze
35+
def initialize(app, key, klass)
36+
@app = app
2837
@deserializable_key = key
2938
@deserializable_class = klass
30-
@deserializable_parser = JSONAPI::Parser::Relationship
3139
end
3240

33-
def deserializable_class
34-
@deserializable_class
35-
end
41+
def call(env)
42+
request = Rack::Request.new(env)
43+
body = request.params.slice(*JSONAPI_KEYS)
44+
parser.parse!(body)
45+
deserialized_hash = @deserializable_class.call(body)
46+
jsonapi = {}
47+
JSONAPI_KEYS.each do |key|
48+
next unless request.params.key?(key)
49+
jsonapi[key.to_sym] = request.delete_param(key)
50+
end
51+
request.update_param(:_jsonapi, jsonapi)
52+
request.update_param(@deserializable_key, deserialized_hash)
3653

37-
def deserializable_key
38-
@deserializable_key
54+
@app.call(env)
3955
end
56+
end
4057

41-
def deserializable_parser
42-
@deserializable_parser
58+
class DeserializeResource < DeserializationMiddleware
59+
def parser
60+
JSONAPI::Parser::Resource
4361
end
4462
end
4563

46-
module InstanceMethods
47-
def params
48-
params = super
49-
key = self.class.deserializable_key
50-
return params if body.key?(key)
51-
parser = self.class.deserializable_parser
52-
return params unless parser
53-
54-
parser.parse!(body)
55-
deserializable_class = self.class.deserializable_class
56-
57-
params.merge!(key => deserializable_class.call(params))
64+
class DeserializeRelationship < DeserializationMiddleware
65+
def parser
66+
JSONAPI::Parser::Relationship
5867
end
5968
end
6069
end

lib/jsonapi/rails/railtie.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ class Railtie < ::Rails::Railtie
3939
end
4040

4141
ActiveSupport.on_load(:action_controller) do
42+
require 'jsonapi/rails/action_controller'
4243
include JSONAPI::Rails::ActionController
4344
end

0 commit comments

Comments
 (0)