jsonapi-utils 0.5.0.beta4 → 0.5.0.beta5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68e34821e946ce803f78ad83fa6515c99dd7e847
4
- data.tar.gz: 52e3849ce3f372eeed8276e4c2ba62815e413e30
3
+ metadata.gz: 9e497750ffb06aad8803f1fb6e85d513ca8eafd4
4
+ data.tar.gz: 7516ec26de1efe29f1666ba3aa49381d0bd033ec
5
5
  SHA512:
6
- metadata.gz: 5b2c8f3ac88c7571ca61148f657de7ffbdf8607a4e22a4136f877801cb2be8ff2e74ba1031c8beec5133fea62d8dad5be1f7199310a9a0011149c035c893d09b
7
- data.tar.gz: f9b02d37f90f04e7e2c224381ace8744127173a9fdba7ce05b1ae8992a4476ca01a59ae8f12dd4de390c17ec4f05009767846af4781806a2de4359904ca0e1c8
6
+ metadata.gz: b1fbb7ff07c127c0f627f2a222f123aae26b6e1782d25f396d35e709ee589fe49a681185c4a350bfb4d43b54972068d70ac9055bef3fa4fe6ac2b2b7478bdc91
7
+ data.tar.gz: 599cf401067538fade2cdc0a75e8c533f8bcd1f313973da8d272d09e5a07bbb4a74c118073e229ae689931ca0f45b6d6cd02fe0c25b21be2a63e8419ded50530
data/README.md CHANGED
@@ -40,18 +40,18 @@ Simple yet powerful way to get your Rails API compliant with [JSON API](http://j
40
40
  Support:
41
41
 
42
42
  * Ruby 2.x with Rails 4.x
43
- * Ruby 2.2.2+ with Rails 5
43
+ * Ruby 2.3+ with Rails 5
44
44
 
45
45
  For Rails 4.x add this to your application's Gemfile:
46
46
 
47
47
  ```ruby
48
- gem 'jsonapi-utils', '~> 0.4.6'
48
+ gem 'jsonapi-utils', '~> 0.4.7'
49
49
  ```
50
50
 
51
51
  For Rails 5, specify the beta version in the Gemfile:
52
52
 
53
53
  ```ruby
54
- gem 'jsonapi-utils', '0.5.0.beta3'
54
+ gem 'jsonapi-utils', '0.5.0.beta5'
55
55
  ```
56
56
 
57
57
  And then execute:
@@ -4,22 +4,88 @@ module JSONAPI
4
4
  module Utils
5
5
  module Exceptions
6
6
  class ActiveRecord < ::JSONAPI::Exceptions::Error
7
- attr_accessor :object
7
+ attr_reader :object, :resource, :relationships, :relationship_keys, :foreign_keys
8
8
 
9
- def initialize(object)
9
+ def initialize(object, resource_klass, context)
10
10
  @object = object
11
+ @resource = resource_klass.new(object, context)
12
+
13
+ # Need to reflect on resource's relationships for error reporting.
14
+ @relationships = resource_klass._relationships.values
15
+ @relationship_keys = @relationships.map(&:name).map(&:to_sym)
16
+ @foreign_keys = @relationships.map(&:foreign_key).map(&:to_sym)
11
17
  end
12
18
 
13
19
  def errors
14
- object.errors.keys.map do |key|
15
- JSONAPI::Error.new(
16
- code: JSONAPI::VALIDATION_ERROR,
17
- status: :unprocessable_entity,
18
- id: key,
19
- title: object.errors.full_messages_for(key).first
20
- )
20
+ object.errors.messages.flat_map do |key, messages|
21
+ messages.map do |message|
22
+ error_meta = error_base
23
+ .merge(title: title_member(key, message))
24
+ .merge(id: id_member(key))
25
+ .merge(source_member(key))
26
+
27
+ JSONAPI::Error.new(error_meta)
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def id_member(key)
35
+ id = resource_key_for(key)
36
+ key_formatter = JSONAPI.configuration.key_formatter
37
+ key_formatter.format(id).to_sym
38
+ end
39
+
40
+ # Determine if this is a foreign key, which will need to look up its
41
+ # matching association name.
42
+ def resource_key_for(key)
43
+ if foreign_keys.include?(key)
44
+ relationships.find { |r| r.foreign_key == key }.name.to_sym
45
+ else
46
+ key
21
47
  end
22
48
  end
49
+
50
+ def source_member(key)
51
+ Hash.new.tap do |hash|
52
+ resource_key = resource_key_for(key)
53
+
54
+ # Pointer should only be created for whitelisted attributes.
55
+ return hash unless resource.fetchable_fields.include?(resource_key) || key == :base
56
+
57
+ id = id_member(key)
58
+
59
+ hash[:source] = {}
60
+ hash[:source][:pointer] =
61
+ # Relationship
62
+ if relationship_keys.include?(resource_key)
63
+ "/data/relationships/#{id}"
64
+ # Base
65
+ elsif key == :base
66
+ '/data'
67
+ # Attribute
68
+ else
69
+ "/data/attributes/#{id}"
70
+ end
71
+ end
72
+ end
73
+
74
+ def title_member(key, message)
75
+ if key == :base
76
+ message
77
+ else
78
+ resource_key = resource_key_for(key)
79
+ [resource_key.to_s.tr('.', '_').humanize, message].join(' ')
80
+ end
81
+ end
82
+
83
+ def error_base
84
+ {
85
+ code: JSONAPI::VALIDATION_ERROR,
86
+ status: :unprocessable_entity
87
+ }
88
+ end
23
89
  end
24
90
 
25
91
  class BadRequest < ::JSONAPI::Exceptions::Error
@@ -1,47 +1,87 @@
1
- module JSONAPI
2
- module Utils
3
- module Request
4
- def jsonapi_request_handling
5
- setup_request
6
- check_request
7
- end
1
+ module JSONAPI::Utils
2
+ module Request
3
+ # Setup and check request before action gets actually evaluated.
4
+ #
5
+ # @api public
6
+ def jsonapi_request_handling
7
+ setup_request
8
+ check_request
9
+ end
8
10
 
9
- def setup_request
10
- @request ||=
11
- JSONAPI::RequestParser.new(
12
- params.dup,
13
- context: context,
14
- key_formatter: key_formatter,
15
- server_error_callbacks: (self.class.server_error_callbacks || [])
16
- )
17
- end
11
+ # Instantiate the request object.
12
+ #
13
+ # @return [JSONAPI::RequestParser]
14
+ #
15
+ # @api public
16
+ def setup_request
17
+ @request ||= JSONAPI::RequestParser.new(
18
+ params,
19
+ context: context,
20
+ key_formatter: key_formatter,
21
+ server_error_callbacks: (self.class.server_error_callbacks || [])
22
+ )
23
+ end
18
24
 
19
- def check_request
20
- @request.errors.blank? || jsonapi_render_errors(json: @request)
21
- end
25
+ # Render an error response if the parsed request got any error.
26
+ #
27
+ # @api public
28
+ def check_request
29
+ @request.errors.blank? || jsonapi_render_errors(json: @request)
30
+ end
22
31
 
23
- def resource_params
24
- build_params_for(:resource)
25
- end
32
+ # Override the JSONAPI::ActsAsResourceController#process_request method.
33
+ #
34
+ # It might be removed when the following line on JR is fixed:
35
+ # https://github.com/cerebris/jsonapi-resources/blob/release-0-8/lib/jsonapi/acts_as_resource_controller.rb#L62
36
+ #
37
+ # @return [String]
38
+ #
39
+ # @api public
40
+ def process_request
41
+ process_operations
42
+ render_results(@operation_results)
43
+ rescue => e
44
+ handle_exceptions(e)
45
+ end
26
46
 
27
- def relationship_params
28
- build_params_for(:relationship)
29
- end
47
+ # Helper to get params for the main resource.
48
+ #
49
+ # @return [Hash]
50
+ #
51
+ # @api public
52
+ def resource_params
53
+ build_params_for(:resource)
54
+ end
55
+
56
+ # Helper to get params for relationship params.
57
+ #
58
+ # @return [Hash]
59
+ #
60
+ # @api public
61
+ def relationship_params
62
+ build_params_for(:relationship)
63
+ end
64
+
65
+ private
30
66
 
31
- private
67
+ # Extract params from request and build a Hash with params
68
+ # for either the main resource or relationships.
69
+ #
70
+ # @return [Hash]
71
+ #
72
+ # @api private
73
+ def build_params_for(param_type)
74
+ return {} if @request.operations.empty?
32
75
 
33
- def build_params_for(param_type)
34
- return {} if @request.operations.empty?
76
+ keys = %i(attributes to_one to_many)
77
+ operation = @request.operations.find { |e| e.options[:data].keys & keys == keys }
35
78
 
36
- keys = %i(attributes to_one to_many)
37
- operation = @request.operations.find { |e| e.options[:data].keys & keys == keys }
38
- if operation.nil?
39
- {}
40
- elsif param_type == :relationship
41
- operation.options[:data].values_at(:to_one, :to_many).compact.reduce(&:merge)
42
- else
43
- operation.options[:data][:attributes]
44
- end
79
+ if operation.nil?
80
+ {}
81
+ elsif param_type == :relationship
82
+ operation.options[:data].values_at(:to_one, :to_many).compact.reduce(&:merge)
83
+ else
84
+ operation.options[:data][:attributes]
45
85
  end
46
86
  end
47
87
  end
@@ -14,7 +14,7 @@ module JSONAPI
14
14
  alias_method :jsonapi_serialize, :jsonapi_format
15
15
 
16
16
  def jsonapi_format_errors(data)
17
- data = JSONAPI::Utils::Exceptions::ActiveRecord.new(data) if data.is_a?(ActiveRecord::Base)
17
+ data = JSONAPI::Utils::Exceptions::ActiveRecord.new(data, @request.resource_klass, context) if data.is_a?(ActiveRecord::Base)
18
18
  errors = data.respond_to?(:errors) ? data.errors : data
19
19
  JSONAPI::Utils::Support::Error.sanitize(errors).uniq
20
20
  end
@@ -47,7 +47,7 @@ module JSONAPI
47
47
  @paginator ||= paginator_klass.new(page_params)
48
48
  end
49
49
 
50
- # Returns the paginator class to be used in the response's pagination.
50
+ # Return the paginator class to be used in the response's pagination.
51
51
  #
52
52
  # @return [Paginator]
53
53
  #
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Utils
3
- VERSION = '0.5.0.beta4'.freeze
3
+ VERSION = '0.5.0.beta5'.freeze
4
4
  end
5
5
  end
data/lib/jsonapi/utils.rb CHANGED
@@ -9,11 +9,10 @@ JSONAPI::Resource.extend JSONAPI::Utils::Support::Filter::Custom
9
9
 
10
10
  module JSONAPI
11
11
  module Utils
12
- include Request
13
- include Response
14
-
15
12
  def self.included(base)
16
13
  base.include ActsAsResourceController
14
+ base.include Request
15
+ base.include Response
17
16
 
18
17
  if base.respond_to?(:before_action)
19
18
  base.before_action :jsonapi_request_handling
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0.beta4
4
+ version: 0.5.0.beta5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Guedes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-10-14 00:00:00.000000000 Z
12
+ date: 2016-12-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: jsonapi-resources
@@ -71,16 +71,16 @@ dependencies:
71
71
  name: rails
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - "~>"
74
+ - - '='
75
75
  - !ruby/object:Gem::Version
76
- version: '4.2'
76
+ version: 5.0.1
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - "~>"
81
+ - - '='
82
82
  - !ruby/object:Gem::Version
83
- version: '4.2'
83
+ version: 5.0.1
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: rspec-rails
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -101,28 +101,28 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '4.5'
104
+ version: '4.8'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: '4.5'
111
+ version: '4.8'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: smart_rspec
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: 0.1.4
118
+ version: 0.1.5
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: 0.1.4
125
+ version: 0.1.5
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: pry
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -198,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
198
  version: 1.3.1
199
199
  requirements: []
200
200
  rubyforge_project:
201
- rubygems_version: 2.5.1
201
+ rubygems_version: 2.6.7
202
202
  signing_key:
203
203
  specification_version: 4
204
204
  summary: JSON::Utils is a simple way to get a full-featured JSON API serialization