jsonapi-utils 0.5.0.beta4 → 0.5.0.beta5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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