jsonapi_errorable 0.7.0 → 0.8.0

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: 490f57c4519b245889df013a2b57572bb4c6ac19
4
- data.tar.gz: 15bcb8cfec13e87914d23be061be69b37ab5b0bf
3
+ metadata.gz: a8db34524ea87abd167f658ec26eac30a013af20
4
+ data.tar.gz: 5cc8882ceaa5a3e0aa8e7aaef7217981bb1a2e99
5
5
  SHA512:
6
- metadata.gz: 2e5c99412abcd2a0a525c33865883b4c8bb95e0882e7bd58cba2666fa56fa585bc33beab9ba0fb5f9aa98a96a992e7ff2aad42acac7e064c0976eab64071fb62
7
- data.tar.gz: a9a79c775278c6eeb75259774728f7ee8021fa5a52feedcc4017b1e504580f3d04f032b6c8ef7194e8d9a9ce87a1fd5b6485987d412efdf6e2afb8b6ebb137ee
6
+ metadata.gz: 191460d4d13635f32e63cebf807c2aeb9069e9e7a81a032f4fec5e2869a5718473298300ebd21cc7a6a55761738de3ca7c3825bfefa16ba7c5767d1b0926926d
7
+ data.tar.gz: 27f3676e471036c8982a2451fec68748d33a1d94084755a05c93b0248d3a833bb6890442b9821aeaaab0f9feab8177532136dde5977505cd576f0be430e893a0
data/.travis.yml CHANGED
@@ -1,8 +1,16 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.3
3
+ - 2.2.3
4
4
  before_install: gem install bundler -v 1.11.2
5
5
 
6
+ script: "bundle exec rake"
7
+
8
+ install: bundle install --retry=3 --jobs=3
9
+
10
+ gemfile:
11
+ - gemfiles/rails_4.gemfile
12
+ - gemfiles/rails_5.gemfile
13
+
6
14
  deploy:
7
15
  provider: rubygems
8
16
  api_key: $RUBYGEMS_API_KEY
data/Rakefile CHANGED
@@ -1,6 +1,11 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "appraisal"
3
4
 
4
5
  RSpec::Core::RakeTask.new(:spec)
5
6
 
6
- task :default => :spec
7
+ if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
8
+ task :default => :appraisal
9
+ else
10
+ task :default => :spec
11
+ end
@@ -1,9 +1,8 @@
1
1
  PATH
2
- remote: ../
2
+ remote: ..
3
3
  specs:
4
- jsonapi_errorable (0.1.1)
5
- active_model_serializers (~> 0.10)
6
- rails (>= 4.1, < 6)
4
+ jsonapi_errorable (0.7.0)
5
+ jsonapi-serializable (~> 0.1)
7
6
 
8
7
  GEM
9
8
  remote: https://rubygems.org/
@@ -27,11 +26,6 @@ GEM
27
26
  erubis (~> 2.7.0)
28
27
  rails-dom-testing (~> 1.0, >= 1.0.5)
29
28
  rails-html-sanitizer (~> 1.0, >= 1.0.2)
30
- active_model_serializers (0.10.2)
31
- actionpack (>= 4.1, < 6)
32
- activemodel (>= 4.1, < 6)
33
- jsonapi (~> 0.1.1.beta2)
34
- railties (>= 4.1, < 6)
35
29
  activejob (4.2.6)
36
30
  activesupport (= 4.2.6)
37
31
  globalid (>= 0.3.0)
@@ -63,8 +57,9 @@ GEM
63
57
  activesupport (>= 4.1.0)
64
58
  i18n (0.7.0)
65
59
  json (1.8.3)
66
- jsonapi (0.1.1.beta2)
67
- json (~> 1.8)
60
+ jsonapi-renderer (0.2.0)
61
+ jsonapi-serializable (0.3.0)
62
+ jsonapi-renderer (~> 0.2.0)
68
63
  jsonapi_spec_helpers (0.2.0)
69
64
  loofah (2.0.3)
70
65
  nokogiri (>= 1.5.9)
@@ -162,4 +157,4 @@ DEPENDENCIES
162
157
  sqlite3
163
158
 
164
159
  BUNDLED WITH
165
- 1.12.5
160
+ 1.15.4
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- jsonapi_errorable (0.6.2)
4
+ jsonapi_errorable (0.7.0)
5
5
  jsonapi-serializable (~> 0.1)
6
6
 
7
7
  GEM
@@ -58,9 +58,9 @@ GEM
58
58
  globalid (0.3.7)
59
59
  activesupport (>= 4.1.0)
60
60
  i18n (0.7.0)
61
- jsonapi-renderer (0.1.2)
62
- jsonapi-serializable (0.1.3)
63
- jsonapi-renderer (~> 0.1)
61
+ jsonapi-renderer (0.2.0)
62
+ jsonapi-serializable (0.3.0)
63
+ jsonapi-renderer (~> 0.2.0)
64
64
  jsonapi_spec_helpers (0.2.0)
65
65
  loofah (2.0.3)
66
66
  nokogiri (>= 1.5.9)
@@ -161,4 +161,4 @@ DEPENDENCIES
161
161
  sqlite3
162
162
 
163
163
  BUNDLED WITH
164
- 1.15.0
164
+ 1.15.4
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency 'jsonapi-serializable', '~> 0.1'
22
22
 
23
+ # Rails is added in Appraisals
23
24
  spec.add_development_dependency "bundler", "~> 1.11"
24
25
  spec.add_development_dependency "rake", "~> 10.0"
25
26
  spec.add_development_dependency "rspec-rails", "~> 3.0"
@@ -3,88 +3,146 @@ module JsonapiErrorable
3
3
  class Validation
4
4
  attr_reader :object
5
5
 
6
- def initialize(object, relationship_params = {}, relationship_message = {})
6
+ def initialize(object, relationship_payloads = {}, relationship_meta = {})
7
7
  @object = object
8
- @relationship_params = relationship_params || {}
9
- @relationship_message = relationship_message
8
+ @relationship_payloads = relationship_payloads
9
+ @relationship_meta = relationship_meta
10
10
  end
11
11
 
12
- def errors
13
- return [] unless object.respond_to?(:errors)
14
-
15
- all_errors = object.errors.to_hash.map do |attribute, messages|
16
- messages.map do |message|
17
- meta = { attribute: attribute, message: message }.merge(@relationship_message)
18
- meta = { relationship: meta } if @relationship_message.present?
19
-
20
- detail = "#{attribute.capitalize} #{message}"
21
-
22
- if attribute.to_s.downcase == 'base'
23
- detail = message
24
- end
25
-
26
- {
12
+ def attribute_errors
13
+ [].tap do |errors|
14
+ each_error do |attribute, message, code|
15
+ error = {
27
16
  code: 'unprocessable_entity',
28
17
  status: '422',
29
18
  title: 'Validation Error',
30
- detail: detail,
19
+ detail: detail_for(attribute, message),
31
20
  source: { pointer: pointer_for(object, attribute) },
32
- meta: meta
21
+ meta: meta_for(attribute, message, code, @relationship_meta)
33
22
  }
23
+
24
+ errors << error
34
25
  end
35
- end.flatten
36
- all_errors << relationship_errors(@relationship_params)
37
- all_errors.flatten!
38
- all_errors.compact!
26
+ end
27
+ end
28
+
29
+ def errors
30
+ return [] unless object.respond_to?(:errors)
31
+
32
+ all_errors = attribute_errors
33
+ all_errors |= relationship_errors(@relationship_payloads)
39
34
  all_errors
40
35
  end
41
36
 
37
+ private
38
+
39
+ def each_error
40
+ object.errors.messages.each_pair do |attribute, messages|
41
+ details = if Rails::VERSION::MAJOR >= 5
42
+ object.errors.details.find { |k,v| k == attribute }[1]
43
+ end
44
+
45
+ messages.each_with_index do |message, index|
46
+ code = details[index][:error] if details
47
+ yield attribute, message, code
48
+ end
49
+ end
50
+ end
51
+
42
52
  def relationship?(name)
43
- return false unless activemodel?
53
+ relationship_names = []
54
+ if activerecord?
55
+ relationship_names = object.class
56
+ .reflect_on_all_associations.map(&:name)
57
+ elsif object.respond_to?(:relationship_names)
58
+ relationship_names = object.relationship_names
59
+ end
44
60
 
45
- relation_names = object.class.reflect_on_all_associations.map(&:name)
46
- relation_names.include?(name)
61
+ relationship_names.include?(name)
47
62
  end
48
63
 
49
64
  def attribute?(name)
50
65
  object.respond_to?(name)
51
66
  end
52
67
 
53
- private
68
+ def meta_for(attribute, message, code, relationship_meta)
69
+ meta = {
70
+ attribute: attribute,
71
+ message: message
72
+ }
73
+ meta.merge!(code: code) if Rails::VERSION::MAJOR >= 5
74
+
75
+ unless relationship_meta.empty?
76
+ meta = {
77
+ relationship: meta.merge(relationship_meta)
78
+ }
79
+ end
80
+
81
+ meta
82
+ end
54
83
 
84
+ def detail_for(attribute, message)
85
+ detail = object.errors.full_message(attribute, message)
86
+ detail = message if attribute.to_s.downcase == 'base'
87
+ detail
88
+ end
89
+
90
+ # @richmolj: Keeping this to support ember-data, but I hate the concept.
55
91
  def pointer_for(object, name)
56
92
  if relationship?(name)
57
93
  "/data/relationships/#{name}"
58
94
  elsif attribute?(name)
59
95
  "/data/attributes/#{name}"
96
+ elsif name == :base
97
+ nil
60
98
  else
61
99
  # Probably a nested relation, like post.comments
62
100
  "/data/relationships/#{name}"
63
101
  end
64
102
  end
65
103
 
66
- def activemodel?
104
+ def activerecord?
67
105
  object.class.respond_to?(:reflect_on_all_associations)
68
106
  end
69
107
 
70
- def relationship_errors(relationship_params)
71
- errors = []
108
+ def traverse_relationships(relationship_params)
109
+ return unless relationship_params
110
+
72
111
  relationship_params.each_pair do |name, payload|
73
- related = Array(@object.send(name))
74
- related.each do |r|
112
+ relationship_objects = Array(@object.send(name))
113
+
114
+ relationship_objects.each do |relationship_object|
115
+ related_payload = payload
75
116
  if payload.is_a?(Array)
76
- related_payload = payload.find { |p| p[:meta][:temp_id] === r.instance_variable_get(:@_jsonapi_temp_id) || p[:meta][:id] == r.id }
77
- else
78
- related_payload = payload
117
+ related_payload = payload.find do |p|
118
+ temp_id = relationship_object
119
+ .instance_variable_get(:@_jsonapi_temp_id)
120
+ p[:meta][:temp_id] === temp_id ||
121
+ p[:meta][:id] == relationship_object.id.to_s
122
+ end
79
123
  end
80
- relationship_message = {
81
- name: name,
82
- id: r.id,
83
- :'temp-id' => r.instance_variable_get(:@_jsonapi_temp_id)
84
- }
85
124
 
86
- errors << Validation.new(r, related_payload[:relationships], relationship_message).errors
125
+ yield name, relationship_object, related_payload
126
+ traverse_relationships(related_payload[:relationships])
127
+ end
128
+ end
129
+ end
130
+
131
+ def relationship_errors(relationship_payloads)
132
+ errors = []
133
+ traverse_relationships(relationship_payloads) do |name, model, payload|
134
+ meta = {}.tap do |hash|
135
+ hash[:name] = name
136
+ hash[:type] = payload[:meta][:jsonapi_type]
137
+ if temp_id = model.instance_variable_get(:@_jsonapi_temp_id)
138
+ hash[:'temp-id'] = temp_id
139
+ else
140
+ hash[:id] = model.id
141
+ end
87
142
  end
143
+
144
+ serializer = self.class.new(model, payload[:relationships], meta)
145
+ errors |= serializer.errors
88
146
  end
89
147
  errors
90
148
  end
@@ -1,3 +1,3 @@
1
1
  module JsonapiErrorable
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_errorable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-29 00:00:00.000000000 Z
11
+ date: 2017-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jsonapi-serializable
@@ -143,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
143
  version: '0'
144
144
  requirements: []
145
145
  rubyforge_project:
146
- rubygems_version: 2.6.13
146
+ rubygems_version: 2.5.1
147
147
  signing_key:
148
148
  specification_version: 4
149
149
  summary: jsonapi.org compatible error handling