levee 0.0.3 → 0.0.4

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: 4c7914e86b72b6401588783ca7bae634b4999da7
4
- data.tar.gz: d9716f4148d31fb9a37fb5d9a3891a5aad3809e5
3
+ metadata.gz: 7c93ba9e7e4b2dd04833b04ae1ece0d87a8fd349
4
+ data.tar.gz: d17711b6b67052cb693b9c34890d3da4feaa0b26
5
5
  SHA512:
6
- metadata.gz: 69a2eb7d1d755284a542f40410eb49b76a4528423c653648210a89ee90a56e5f163a7c301d66c78cd1e014ee18c2b0759b1d22458b6f7b9762da863304678d88
7
- data.tar.gz: 08ea0de0d98c6f98645cbe5cf67ef6112a6b3afaa7561745c36741adca7ed4456255871004722c938e692ce826b9f8e30978a2febd573111515d219511dfe7e1
6
+ metadata.gz: 64e427d6f9d8a2d16cd6e9168139a68e49e56e582fbb01309e5ac7ac446989a12f5c29570af79ded87eae6a1d504eb7b184ca94ece50accdcf667c1d461b17c7
7
+ data.tar.gz: 9d53286d208e26ff64c38d6e330cb11e7500bb13c18c989f1ab45c1b50daf4e229280335a93ff30c348c08209460d744e12dd7fc144a2c534737b9611bebcc5f
@@ -0,0 +1,36 @@
1
+ module JsonApi
2
+
3
+ def included
4
+ @included
5
+ end
6
+
7
+ def included=(v)
8
+ @included = v
9
+ end
10
+
11
+ def set_params_using_adapter(params)
12
+ self.params = params[:data]
13
+ self.included = params[:included]
14
+ validate_params
15
+ validate_included
16
+ end
17
+
18
+ def validate_params
19
+ message = "Params passed to a builder using :json_api adapter must be a hash with the root_node data"
20
+ raise message unless params.respond_to?(:fetch)
21
+ return true if params.is_a? Array
22
+ message = "Params passed to builder must not have a root node"
23
+ key = params.keys.first
24
+ raise message if key && key.to_s.camelize == object_class.to_s
25
+ end
26
+
27
+ def validate_included
28
+ message = "Params passed to builder must be a hash"
29
+ raise message unless params.respond_to?(:fetch)
30
+ return true if params.is_a? Array
31
+ message = "Params passed to builder must not have a root node"
32
+ key = params.keys.first
33
+ raise message if key && key.to_s.camelize == object_class.to_s
34
+ end
35
+
36
+ end
@@ -10,8 +10,7 @@ module Levee
10
10
  :builder_options
11
11
 
12
12
  def initialize(params, options={}, &blk)
13
- self.params = params
14
- validate_params
13
+ set_params_using_adapter(params)
15
14
  self.errors = []
16
15
  self.nested_objects_to_save = []
17
16
  self.permitted_attributes = [:id]
@@ -24,6 +23,7 @@ module Levee
24
23
  unless params.is_a? Array
25
24
  self.object = object_class.find_by(id: params[:id]) || object_class.new
26
25
  end
26
+ Rails.logger.debug({message: "#{self.class} building object", object: object, parmas: params })
27
27
  assign_parameters_in_transaction
28
28
  end
29
29
 
@@ -54,6 +54,10 @@ module Levee
54
54
  begin
55
55
  perform_in_transaction
56
56
  rescue => e
57
+ Rails.logger.warn({message: "Error caught in builder",
58
+ error: e,
59
+ builder: self,
60
+ params: params})
57
61
  raise_error = -> { raise e }
58
62
  rescue_errors(e) || raise_error.call
59
63
  ensure
@@ -61,15 +65,16 @@ module Levee
61
65
  raise ActiveRecord::Rollback unless errors.flatten.empty?
62
66
  end
63
67
  end
64
- Rails.logger.error "Builder Errors:"
65
- Rails.logger.error errors.to_yaml
66
- self.object = object.reload if errors.empty? && object.try(:persisted?)
68
+ Rails.logger.warn({message: "Builder Errors",
69
+ errors: errors})
70
+ # self.object = object.reload if errors.empty? && object.try(:persisted?)
67
71
  errors.empty? ? object : {errors: errors, error_status: errors.first[:status]}
68
72
  end
69
73
 
70
74
  def perform_in_transaction
71
- self.errors += validator.validate_params.errors if validator
75
+ self.errors += validator.validate_params(builder_options).errors if validator
72
76
  return false if errors.any?
77
+ flatten_attributes
73
78
  self.object = top_level_array || call_setter_for_each_param_key
74
79
  return true unless requires_save && !top_level_array
75
80
  before_save_callbacks.each { |callback| send(callback) }
@@ -80,6 +85,7 @@ module Levee
80
85
  end
81
86
 
82
87
  def call_setter_for_each_param_key
88
+ Rails.logger.info({message: "Attributes being set:", attributes: params})
83
89
  params.each do |key, value|
84
90
  send_if_key_included_in_attributes(key.to_sym, value)
85
91
  end
@@ -90,7 +96,11 @@ module Levee
90
96
  if permitted_attributes.include?(key)
91
97
  self.send(key, value)
92
98
  else
93
- errors << {status: 400, message: "Unpermitted parameter key #{key}"}
99
+ error = {status: 400, message: "Unpermitted parameter key #{key}"}
100
+ errors << error
101
+ Rails.logger.warn({message: "Unpermitted parameter key, not listed in #{self.class} attributes",
102
+ key: key,
103
+ listed_attributes: permitted_attributes})
94
104
  raise ActiveRecord::Rollback
95
105
  end
96
106
  end
@@ -110,6 +120,10 @@ module Levee
110
120
  rescue => e
111
121
  if params.has_key?(method_name)
112
122
  message = "Unable to process value for :#{method_name}, no attribute writer. Be sure to override the automatic setters for all params that do not map straight to a model attribute."
123
+ Rails.logger.warn({message: message,
124
+ missing_writer: method_name,
125
+ value: args.first,
126
+ error: error})
113
127
  self.errors << {status: 422, message: message}
114
128
  else
115
129
  raise e
@@ -146,7 +160,10 @@ module Levee
146
160
 
147
161
  def raise_if_validation_error(rescued_error)
148
162
  if rescued_error.is_a? ActiveRecord::RecordInvalid
149
- self.errors << { status: 422, code: 'validation_error', message: object.errors.full_messages, record: rescued_error.record }
163
+ error = { status: 422, code: 'validation_error', message: rescued_error.message, full_messages: object.errors.full_messages, record: rescued_error.record, error: rescued_error }
164
+ Rails.logger.warn error
165
+ self.errors << error
166
+ Rails.warn "Transaction rolled back"
150
167
  raise ActiveRecord::Rollback
151
168
  end
152
169
  end
@@ -154,14 +171,20 @@ module Levee
154
171
  def raise_if_argument_error(rescued_error)
155
172
  if rescued_error.is_a? ArgumentError
156
173
  message = "All methods on the builder that override attribute setters must accept one argument to catch the parameter value"
157
- self.errors << { status: 500, code: 'builder_error', message: message }
174
+ error = { status: 500, code: 'builder_error', message: message, error: rescued_error }
175
+ Rails.logger.error error
176
+ self.errors << error
177
+ Rails.warn "Transaction rolled back"
158
178
  raise ArgumentError.new message
159
179
  end
160
180
  end
161
181
 
162
182
  def raise_if_unknown_attribute_error(rescued_error)
163
183
  if rescued_error.is_a? ActiveRecord::UnknownAttributeError
164
- self.errors << { status: 400, code: 'unknown_attribute_error', message: rescued_error.message, record: rescued_error.record }
184
+ error = { status: 400, code: 'unknown_attribute_error', message: rescued_error.message, record: rescued_error.record, error: rescued_error, trace: rescued_error.backtrace }
185
+ Rails.logger.warn error
186
+ self.errors << error
187
+ Rails.warn "Transaction rolled back"
165
188
  raise ActiveRecord::Rollback
166
189
  end
167
190
  end
@@ -177,11 +200,13 @@ module Levee
177
200
 
178
201
  def validate_params
179
202
  message = "Params passed to builder must be a hash or top level array"
203
+ # Rails.logger.error message
180
204
  raise message unless params.respond_to?(:fetch)
181
205
  return true if params.is_a? Array
182
206
  message = "Params passed to builder must not have a root node"
183
207
  key = params.keys.first
184
208
  raise message if key && key.to_s.camelize == object_class.to_s
209
+ Rails.logger.debug({message: "Params passed validation", builder: "self.class", params: params})
185
210
  end
186
211
 
187
212
  #used so that id setter is not called by default
@@ -226,5 +251,41 @@ module Levee
226
251
  def self._validator
227
252
  @validator
228
253
  end
254
+
255
+ def self.set_adapter(adapter)
256
+ adapter_module = adapter.to_s.camelize.constantize
257
+ self.include adapter_module
258
+ self.extend adapter_module
259
+ end
260
+
261
+ def set_params_using_adapter(params)
262
+ self.params = params
263
+ validate_params
264
+ end
265
+
266
+ def flatten_attributes
267
+ if params.is_a?(Hash)
268
+ self.params = flatten_hash(params)
269
+ elsif params.is_a?(Array)
270
+ self.params = flatten_array
271
+ end
272
+ end
273
+
274
+ def flatten_array
275
+ params.map do |p|
276
+ flatten_hash(p)
277
+ end
278
+ end
279
+
280
+ def flatten_hash(val)
281
+ if val.fetch(:attributes, nil)
282
+ p = val.dup
283
+ p[:attributes][:id] = val[:id] if val[:id]
284
+ p[:attributes][:type] = val[:type] if val[:type]
285
+ p[:attributes]
286
+ else
287
+ val
288
+ end
289
+ end
229
290
  end
230
291
  end
@@ -1,13 +1,14 @@
1
1
  module Levee
2
2
  class Validator
3
- attr_accessor :errors, :params
3
+ attr_accessor :errors, :params, :builder_options
4
4
 
5
5
  def initialize(params)
6
6
  self.errors = []
7
7
  self.params = params
8
8
  end
9
9
 
10
- def validate_params
10
+ def validate_params(builder_options = {})
11
+ @builder_options = builder_options
11
12
  validations.each { |val| send(val) }
12
13
  self
13
14
  end
@@ -1,7 +1,7 @@
1
1
  module Levee
2
2
  extend self
3
3
 
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.4"
5
5
 
6
6
  def gem_description
7
7
  %Q(The purpose of the builder object is to create a layer of abstraction between the controller and models in a Rails application. The builder is particularly useful for receiving complex post and put requests with multiple parameters, but is lightweight enough to use for simple writes when some filtering or parameter combination validation might be useful before writing to the database. Since it wraps the entire write action to mulitple models in a single transaction, any failure in the builder will result in the entire request being rolled back.)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: levee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Martinson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-18 00:00:00.000000000 Z
11
+ date: 2015-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -70,9 +70,9 @@ files:
70
70
  - LICENSE.txt
71
71
  - README.md
72
72
  - Rakefile
73
- - levee-0.0.2.gem
74
73
  - levee.gemspec
75
74
  - lib/levee.rb
75
+ - lib/levee/adapters/json_api.rb
76
76
  - lib/levee/builder.rb
77
77
  - lib/levee/validator.rb
78
78
  - lib/levee/version.rb
Binary file