jsonapi_errorable 0.7.0 → 0.8.0

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: 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