snfoil 0.7.0 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +514 -1
- data/lib/sn_foil/adapters/orms/active_record.rb +0 -4
- data/lib/sn_foil/adapters/orms/base_adapter.rb +10 -0
- data/lib/sn_foil/contexts/change_context.rb +3 -2
- data/lib/sn_foil/contexts/create_context.rb +3 -2
- data/lib/sn_foil/contexts/destroy_context.rb +3 -2
- data/lib/sn_foil/contexts/setup_context.rb +1 -0
- data/lib/sn_foil/contexts/update_context.rb +4 -3
- data/lib/sn_foil/policy.rb +1 -0
- data/lib/sn_foil/searcher.rb +24 -5
- data/lib/sn_foil/version.rb +1 -1
- metadata +31 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8328aacb27ef6711cd1b25c3c7fbe5654a5bc29c8ceee571ffd8046ea39ee250
|
4
|
+
data.tar.gz: 39a1b64d79149181a5096a1e27f711c5a824444070c2213771230ab734970356
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50eeacc458500736909ae891189aec51619ac9258882c8c992504939e93f4ad8a2fed1a51b6a282e7d03ca56f847fd2293be368a708587ccee5aa0d657bd42df
|
7
|
+
data.tar.gz: c2d0e681ac70c2d02eb457ced8fbac47dfd830183e3355b9a77c0cf55ad50e4b0f946484fdcff2b5ff70f6e783c95c4ddf66831a8a07f81f13a8b6c2c8b7e290
|
data/README.md
CHANGED
@@ -22,7 +22,520 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
|
25
|
+
|
26
|
+
### Major Components
|
27
|
+
|
28
|
+
#### Model
|
29
|
+
#### Policy
|
30
|
+
#### Searcher
|
31
|
+
|
32
|
+
## Contexts
|
33
|
+
Contexts are groupings of common actions that a certain entity can perform.
|
34
|
+
|
35
|
+
### Data
|
36
|
+
|
37
|
+
### Actions
|
38
|
+
|
39
|
+
SnFoil Contexts handle basic CRUD through a few different actions
|
40
|
+
|
41
|
+
<table>
|
42
|
+
<thead>
|
43
|
+
<th>Action</th>
|
44
|
+
<th>Description</th>
|
45
|
+
</thead>
|
46
|
+
<tbody>
|
47
|
+
<tr>
|
48
|
+
<td>Build</td>
|
49
|
+
<td>
|
50
|
+
The action on setting up a model but not persiting.
|
51
|
+
<div>
|
52
|
+
<i>Author's note:</i> So far I have just been using this so factories in testing follow the same setup logic as a context would.
|
53
|
+
</div>
|
54
|
+
</td>
|
55
|
+
</tr>
|
56
|
+
<tr>
|
57
|
+
<td>Create</td>
|
58
|
+
<td>The action of setting up a model and persisting it.</td>
|
59
|
+
</tr>
|
60
|
+
<tr>
|
61
|
+
<td>Update</td>
|
62
|
+
<td>The action of finding a pre-existing model and updating the attributes.</td>
|
63
|
+
</tr>
|
64
|
+
<tr>
|
65
|
+
<td>Destroy</td>
|
66
|
+
<td>The action of finding a pre-existing model and destroying it.</td>
|
67
|
+
</tr>
|
68
|
+
<tr>
|
69
|
+
<td>Show</td>
|
70
|
+
<td>The action of finding a pre-existing model by an identifier.</td>
|
71
|
+
</tr>
|
72
|
+
<tr>
|
73
|
+
<td>Index</td>
|
74
|
+
<td>The action of finding a pre-existing models by using a searcher.</td>
|
75
|
+
</tr>
|
76
|
+
</tbody>
|
77
|
+
</table>
|
78
|
+
|
79
|
+
### Methods
|
80
|
+
Methods allow users to create inheritable actions that occur in a specific order. Methods will always run before their hook counterpart. Since these are inheritable, you can chain needed actions all the way through the parent heirarchy by using the `super` keyword.
|
81
|
+
|
82
|
+
<strong>Important Note</strong> Methods <u>always</u> need to return the options hash at the end.
|
83
|
+
|
84
|
+
<i>Author's opinion:</i> While simplier than hooks, they do not allow for as clean of a composition as hooks.
|
85
|
+
|
86
|
+
#### Example
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
# Call the webhooks for third party integrations
|
90
|
+
# Commit business logic to internal process
|
91
|
+
def after_create_success(**options)
|
92
|
+
options = super
|
93
|
+
|
94
|
+
call_webhook_for_model(options[:object])
|
95
|
+
finalize_business_logic(options[:object])
|
96
|
+
|
97
|
+
options
|
98
|
+
end
|
99
|
+
|
100
|
+
# notify error tracker
|
101
|
+
def after_create_error(**options)
|
102
|
+
options = super
|
103
|
+
|
104
|
+
notify_errors(options[:object].errors)
|
105
|
+
|
106
|
+
options
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
### Hooks
|
111
|
+
Hooks make it very easy to compose multiple actions that need to occur in a specific order. You can have as many repeated hooks as you would like. This makes defining single responsibility hooks very simple, and they will get called in the order they are defined. The major downside of hooks are that they are currently not inheritable.
|
112
|
+
|
113
|
+
<strong>Important Note</strong> Hooks <u>always</u> need to return the options hash at the end.
|
114
|
+
|
115
|
+
#### Example
|
116
|
+
Lets take the Method example and make it into hooks instead.
|
117
|
+
```ruby
|
118
|
+
# Call the webhooks for third party integrations
|
119
|
+
after_create_success do |options|
|
120
|
+
call_webhook_for_model(options[:object])
|
121
|
+
options
|
122
|
+
end
|
123
|
+
|
124
|
+
# Commit business logic to internal process
|
125
|
+
after_create_success do |options|
|
126
|
+
finalize_business_logic(options[:object])
|
127
|
+
options
|
128
|
+
end
|
129
|
+
|
130
|
+
# notify error tracker
|
131
|
+
after_create_error do |options|
|
132
|
+
notify_errors(options[:object].errors)
|
133
|
+
options
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
137
|
+
<table>
|
138
|
+
<thead>
|
139
|
+
<th>Name</th>
|
140
|
+
<th>Timing</th>
|
141
|
+
<th>Description</th>
|
142
|
+
</thead>
|
143
|
+
<tbody>
|
144
|
+
<tr>
|
145
|
+
<td>setup</td>
|
146
|
+
<td>-Always at the beginning</td>
|
147
|
+
<td>Primarily used for basic setup logic that always needs to occur</td>
|
148
|
+
</tr>
|
149
|
+
<tr>
|
150
|
+
<td>setup_<action></td>
|
151
|
+
<td>-Before the object has been found or created</td>
|
152
|
+
<td>Primarily used for basic setup logic that only needs to occur for certain actions</td>
|
153
|
+
</tr>
|
154
|
+
<tr>
|
155
|
+
<td>before_<action></td>
|
156
|
+
<td>
|
157
|
+
<div>-After the object has been found or created</div>
|
158
|
+
<div>-Before the object has been persisted/altered</div>
|
159
|
+
</td>
|
160
|
+
<td></td>
|
161
|
+
</tr>
|
162
|
+
<tr>
|
163
|
+
<td>after_<action>_success</td>
|
164
|
+
<td>-After the object has been successfully been persisted/altered</td>
|
165
|
+
<td></td>
|
166
|
+
</tr>
|
167
|
+
<tr>
|
168
|
+
<td>after_<action>_failure</td>
|
169
|
+
<td>-After an error has occured persisting/altering the object</td>
|
170
|
+
<td></td>
|
171
|
+
<tr>
|
172
|
+
<td>after_<action></td>
|
173
|
+
<td>-Always at the end</td>
|
174
|
+
<td></td>
|
175
|
+
</tr>
|
176
|
+
</tr>
|
177
|
+
</tbody>
|
178
|
+
<table>
|
179
|
+
|
180
|
+
### Call Order
|
181
|
+
|
182
|
+
The call order for actions is extremely important because SnFoil passes the options hash throughout the entire process. So any data you may need down the call order can be added earlier in the stack.
|
183
|
+
|
184
|
+
<table>
|
185
|
+
<thead>
|
186
|
+
<tr>
|
187
|
+
<th rowspan="2">Action</th>
|
188
|
+
<th colspan="2">Order</th>
|
189
|
+
</tr>
|
190
|
+
<tr>
|
191
|
+
<th>Type</th>
|
192
|
+
<th>Name</th>
|
193
|
+
</tr>
|
194
|
+
</thead>
|
195
|
+
<tbody>
|
196
|
+
<tr>
|
197
|
+
<td rowspan="5">Build</td>
|
198
|
+
</tr>
|
199
|
+
<tr>
|
200
|
+
<td>Method</td>
|
201
|
+
<td>setup</td>
|
202
|
+
</tr>
|
203
|
+
<tr>
|
204
|
+
<td>Hooks</td>
|
205
|
+
<td>setup</td>
|
206
|
+
</tr>
|
207
|
+
<tr>
|
208
|
+
<td>Method</td>
|
209
|
+
<td>setup_build</td>
|
210
|
+
</tr>
|
211
|
+
<tr>
|
212
|
+
<td>Hooks</td>
|
213
|
+
<td>setup_build</td>
|
214
|
+
</tr>
|
215
|
+
<tr><td rowspan="25">Create</td></tr>
|
216
|
+
<tr>
|
217
|
+
<td>Method</td>
|
218
|
+
<td>setup</td>
|
219
|
+
</tr>
|
220
|
+
<tr>
|
221
|
+
<td>Hooks</td>
|
222
|
+
<td>setup</td>
|
223
|
+
</tr>
|
224
|
+
<tr>
|
225
|
+
<td>Method</td>
|
226
|
+
<td>setup_build</td>
|
227
|
+
</tr>
|
228
|
+
<tr>
|
229
|
+
<td>Hooks</td>
|
230
|
+
<td>setup_build</td>
|
231
|
+
</tr>
|
232
|
+
<tr>
|
233
|
+
<td>Method</td>
|
234
|
+
<td>setup_change</td>
|
235
|
+
</tr>
|
236
|
+
<tr>
|
237
|
+
<td>Hooks</td>
|
238
|
+
<td>setup_change</td>
|
239
|
+
</tr>
|
240
|
+
<tr>
|
241
|
+
<td>Method</td>
|
242
|
+
<td>setup_create</td>
|
243
|
+
</tr>
|
244
|
+
<tr>
|
245
|
+
<td>Hooks</td>
|
246
|
+
<td>setup_create</td>
|
247
|
+
</tr>
|
248
|
+
<tr>
|
249
|
+
<td>Method</td>
|
250
|
+
<td>before_change</td>
|
251
|
+
</tr>
|
252
|
+
<tr>
|
253
|
+
<td>Hooks</td>
|
254
|
+
<td>before_change</td>
|
255
|
+
</tr>
|
256
|
+
<tr>
|
257
|
+
<td>Method</td>
|
258
|
+
<td>before_create</td>
|
259
|
+
</tr>
|
260
|
+
<tr>
|
261
|
+
<td>Hooks</td>
|
262
|
+
<td>before_create</td>
|
263
|
+
</tr>
|
264
|
+
<tr>
|
265
|
+
<td>Method</td>
|
266
|
+
<td><i>*after_change_success</i</td>
|
267
|
+
</tr>
|
268
|
+
<tr>
|
269
|
+
<td>Hooks</td>
|
270
|
+
<td><i>*after_change_success</i</td>
|
271
|
+
</tr>
|
272
|
+
<tr>
|
273
|
+
<td>Method</td>
|
274
|
+
<td><i>*after_create_success</i</td>
|
275
|
+
</tr>
|
276
|
+
<tr>
|
277
|
+
<td>Hooks</td>
|
278
|
+
<td><i>*after_create_success</i</td>
|
279
|
+
</tr>
|
280
|
+
<tr>
|
281
|
+
<td>Method</td>
|
282
|
+
<td><i>*after_change_failure</i</td>
|
283
|
+
</tr>
|
284
|
+
<tr>
|
285
|
+
<td>Hooks</td>
|
286
|
+
<td><i>*after_change_failure</i</td>
|
287
|
+
</tr>
|
288
|
+
<tr>
|
289
|
+
<td>Method</td>
|
290
|
+
<td><i>*after_create_failure</i</td>
|
291
|
+
</tr>
|
292
|
+
<tr>
|
293
|
+
<td>Hooks</td>
|
294
|
+
<td><i>*after_create_failure</i</td>
|
295
|
+
</tr>
|
296
|
+
<tr>
|
297
|
+
<td>Method</td>
|
298
|
+
<td>after_change</td>
|
299
|
+
</tr>
|
300
|
+
<tr>
|
301
|
+
<td>Hooks</td>
|
302
|
+
<td>after_change</td>
|
303
|
+
</tr>
|
304
|
+
<tr>
|
305
|
+
<td>Method</td>
|
306
|
+
<td>after_create</td>
|
307
|
+
</tr>
|
308
|
+
<tr>
|
309
|
+
<td>Hooks</td>
|
310
|
+
<td>after_create</td>
|
311
|
+
</tr>
|
312
|
+
<tr><td rowspan="23">Update</td></tr>
|
313
|
+
<tr>
|
314
|
+
<td>Method</td>
|
315
|
+
<td>setup</td>
|
316
|
+
</tr>
|
317
|
+
<tr>
|
318
|
+
<td>Hooks</td>
|
319
|
+
<td>setup</td>
|
320
|
+
</tr>
|
321
|
+
<tr>
|
322
|
+
<td>Method</td>
|
323
|
+
<td>setup_change</td>
|
324
|
+
</tr>
|
325
|
+
<tr>
|
326
|
+
<td>Hooks</td>
|
327
|
+
<td>setup_change</td>
|
328
|
+
</tr>
|
329
|
+
<tr>
|
330
|
+
<td>Method</td>
|
331
|
+
<td>setup_update</td>
|
332
|
+
</tr>
|
333
|
+
<tr>
|
334
|
+
<td>Hooks</td>
|
335
|
+
<td>setup_update</td>
|
336
|
+
</tr>
|
337
|
+
<tr>
|
338
|
+
<td>Method</td>
|
339
|
+
<td>before_change</td>
|
340
|
+
</tr>
|
341
|
+
<tr>
|
342
|
+
<td>Hooks</td>
|
343
|
+
<td>before_change</td>
|
344
|
+
</tr>
|
345
|
+
<tr>
|
346
|
+
<td>Method</td>
|
347
|
+
<td>before_update</td>
|
348
|
+
</tr>
|
349
|
+
<tr>
|
350
|
+
<td>Hooks</td>
|
351
|
+
<td>before_update</td>
|
352
|
+
</tr>
|
353
|
+
<tr>
|
354
|
+
<td>Method</td>
|
355
|
+
<td><i>*after_change_success</i</td>
|
356
|
+
</tr>
|
357
|
+
<tr>
|
358
|
+
<td>Hooks</td>
|
359
|
+
<td><i>*after_change_success</i</td>
|
360
|
+
</tr>
|
361
|
+
<tr>
|
362
|
+
<td>Method</td>
|
363
|
+
<td><i>*after_update_success</i</td>
|
364
|
+
</tr>
|
365
|
+
<tr>
|
366
|
+
<td>Hooks</td>
|
367
|
+
<td><i>*after_update_success</i</td>
|
368
|
+
</tr>
|
369
|
+
<tr>
|
370
|
+
<td>Method</td>
|
371
|
+
<td><i>*after_change_failure</i</td>
|
372
|
+
</tr>
|
373
|
+
<tr>
|
374
|
+
<td>Hooks</td>
|
375
|
+
<td><i>*after_change_failure</i</td>
|
376
|
+
</tr>
|
377
|
+
<tr>
|
378
|
+
<td>Method</td>
|
379
|
+
<td><i>*after_update_failure</i</td>
|
380
|
+
</tr>
|
381
|
+
<tr>
|
382
|
+
<td>Hooks</td>
|
383
|
+
<td><i>*after_update_failure</i</td>
|
384
|
+
</tr>
|
385
|
+
<tr>
|
386
|
+
<td>Method</td>
|
387
|
+
<td>after_change</td>
|
388
|
+
</tr>
|
389
|
+
<tr>
|
390
|
+
<td>Hooks</td>
|
391
|
+
<td>after_change</td>
|
392
|
+
</tr>
|
393
|
+
<tr>
|
394
|
+
<td>Method</td>
|
395
|
+
<td>after_update</td>
|
396
|
+
</tr>
|
397
|
+
<tr>
|
398
|
+
<td>Hooks</td>
|
399
|
+
<td>after_update</td>
|
400
|
+
</tr>
|
401
|
+
<tr><td rowspan="23">Destroy</td></tr>
|
402
|
+
<tr>
|
403
|
+
<td>Method</td>
|
404
|
+
<td>setup</td>
|
405
|
+
</tr>
|
406
|
+
<tr>
|
407
|
+
<td>Hooks</td>
|
408
|
+
<td>setup</td>
|
409
|
+
</tr>
|
410
|
+
<tr>
|
411
|
+
<td>Method</td>
|
412
|
+
<td>setup_change</td>
|
413
|
+
</tr>
|
414
|
+
<tr>
|
415
|
+
<td>Hooks</td>
|
416
|
+
<td>setup_change</td>
|
417
|
+
</tr>
|
418
|
+
<tr>
|
419
|
+
<td>Method</td>
|
420
|
+
<td>setup_destroy</td>
|
421
|
+
</tr>
|
422
|
+
<tr>
|
423
|
+
<td>Hooks</td>
|
424
|
+
<td>setup_destroy</td>
|
425
|
+
</tr>
|
426
|
+
<tr>
|
427
|
+
<td>Method</td>
|
428
|
+
<td>before_change</td>
|
429
|
+
</tr>
|
430
|
+
<tr>
|
431
|
+
<td>Hooks</td>
|
432
|
+
<td>before_change</td>
|
433
|
+
</tr>
|
434
|
+
<tr>
|
435
|
+
<td>Method</td>
|
436
|
+
<td>before_destroy</td>
|
437
|
+
</tr>
|
438
|
+
<tr>
|
439
|
+
<td>Hooks</td>
|
440
|
+
<td>before_destroy</td>
|
441
|
+
</tr>
|
442
|
+
<tr>
|
443
|
+
<td>Method</td>
|
444
|
+
<td><i>*after_change_success</i</td>
|
445
|
+
</tr>
|
446
|
+
<tr>
|
447
|
+
<td>Hooks</td>
|
448
|
+
<td><i>*after_change_success</i</td>
|
449
|
+
</tr>
|
450
|
+
<tr>
|
451
|
+
<td>Method</td>
|
452
|
+
<td><i>*after_destroy_success</i</td>
|
453
|
+
</tr>
|
454
|
+
<tr>
|
455
|
+
<td>Hooks</td>
|
456
|
+
<td><i>*after_destroy_success</i</td>
|
457
|
+
</tr>
|
458
|
+
<tr>
|
459
|
+
<td>Method</td>
|
460
|
+
<td><i>*after_change_failure</i</td>
|
461
|
+
</tr>
|
462
|
+
<tr>
|
463
|
+
<td>Hooks</td>
|
464
|
+
<td><i>*after_change_failure</i</td>
|
465
|
+
</tr>
|
466
|
+
<tr>
|
467
|
+
<td>Method</td>
|
468
|
+
<td><i>*after_destroy_failure</i</td>
|
469
|
+
</tr>
|
470
|
+
<tr>
|
471
|
+
<td>Hooks</td>
|
472
|
+
<td><i>*after_destroy_failure</i</td>
|
473
|
+
</tr>
|
474
|
+
<tr>
|
475
|
+
<td>Method</td>
|
476
|
+
<td>after_change</td>
|
477
|
+
</tr>
|
478
|
+
<tr>
|
479
|
+
<td>Hooks</td>
|
480
|
+
<td>after_change</td>
|
481
|
+
</tr>
|
482
|
+
<tr>
|
483
|
+
<td>Method</td>
|
484
|
+
<td>after_destroy</td>
|
485
|
+
</tr>
|
486
|
+
<tr>
|
487
|
+
<td>Hooks</td>
|
488
|
+
<td>after_destroy</td>
|
489
|
+
</tr>
|
490
|
+
<tr>
|
491
|
+
<td rowspan="5">Show</td>
|
492
|
+
</tr>
|
493
|
+
<tr>
|
494
|
+
<td>Method</td>
|
495
|
+
<td>setup</td>
|
496
|
+
</tr>
|
497
|
+
<tr>
|
498
|
+
<td>Hooks</td>
|
499
|
+
<td>setup</td>
|
500
|
+
</tr>
|
501
|
+
<tr>
|
502
|
+
<td>Method</td>
|
503
|
+
<td>setup_show</td>
|
504
|
+
</tr>
|
505
|
+
<tr>
|
506
|
+
<td>Hooks</td>
|
507
|
+
<td>setup_show</td>
|
508
|
+
</tr>
|
509
|
+
<tr>
|
510
|
+
<td rowspan="5">Index</td>
|
511
|
+
</tr>
|
512
|
+
<tr>
|
513
|
+
<td>Method</td>
|
514
|
+
<td>setup</td>
|
515
|
+
</tr>
|
516
|
+
<tr>
|
517
|
+
<td>Hooks</td>
|
518
|
+
<td>setup</td>
|
519
|
+
</tr>
|
520
|
+
<tr>
|
521
|
+
<td>Method</td>
|
522
|
+
<td>setup_index</td>
|
523
|
+
</tr>
|
524
|
+
<tr>
|
525
|
+
<td>Hooks</td>
|
526
|
+
<td>setup_index</td>
|
527
|
+
</tr>
|
528
|
+
</tbody>
|
529
|
+
<table>
|
530
|
+
|
531
|
+
<div>
|
532
|
+
* only occurs depeding on the success or failure of the action
|
533
|
+
</div>
|
534
|
+
|
535
|
+
## Policies
|
536
|
+
|
537
|
+
## Searchers
|
538
|
+
|
26
539
|
|
27
540
|
## Development
|
28
541
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'delegate'
|
4
|
+
|
3
5
|
module SnFoil
|
4
6
|
module Adapters
|
5
7
|
module ORMs
|
@@ -23,6 +25,14 @@ module SnFoil
|
|
23
25
|
def attributes=(_attributes)
|
24
26
|
raise NotImplementedError, '#attributes= not implemented in adapter'
|
25
27
|
end
|
28
|
+
|
29
|
+
def is_a?(check_class)
|
30
|
+
__getobj__.class.object_id.equal?(check_class.object_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def klass
|
34
|
+
__getobj__.class
|
35
|
+
end
|
26
36
|
end
|
27
37
|
end
|
28
38
|
end
|
@@ -15,9 +15,10 @@ module SnFoil
|
|
15
15
|
class_methods do # rubocop:disable Metrics/BlockLength
|
16
16
|
attr_reader :i_params, :i_setup_change_hooks, :i_before_change_hooks, :i_after_change_hooks,
|
17
17
|
:i_after_change_success_hooks, :i_after_change_failure_hooks
|
18
|
-
|
18
|
+
|
19
|
+
def params(*permitted_params)
|
19
20
|
@i_params ||= []
|
20
|
-
@i_params |=
|
21
|
+
@i_params |= permitted_params
|
21
22
|
end
|
22
23
|
|
23
24
|
def setup_change(method = nil, **options, &block)
|
@@ -18,6 +18,7 @@ module SnFoil
|
|
18
18
|
class_methods do
|
19
19
|
attr_reader :i_setup_create_hooks, :i_before_create_hooks, :i_after_create_hooks,
|
20
20
|
:i_after_create_success_hooks, :i_after_create_failure_hooks
|
21
|
+
|
21
22
|
def create(params:, entity: nil, **options)
|
22
23
|
new(entity).create(**options, params: params)
|
23
24
|
end
|
@@ -58,7 +59,7 @@ module SnFoil
|
|
58
59
|
options = before_setup_build_object(**options)
|
59
60
|
options = before_setup_create_object(**options)
|
60
61
|
options = setup_create_object(**options)
|
61
|
-
authorize(options[:object], options.fetch(:authorize
|
62
|
+
authorize(options[:object], options.fetch(:authorize, :create?), **options)
|
62
63
|
options = create_hooks(**options)
|
63
64
|
options[:object]
|
64
65
|
end
|
@@ -116,7 +117,7 @@ module SnFoil
|
|
116
117
|
def create_hooks(options)
|
117
118
|
options = before_create_save(**options)
|
118
119
|
save_successful = options[:object].save
|
119
|
-
options
|
120
|
+
options[:object] = unwrap_object(options[:object])
|
120
121
|
options = if save_successful
|
121
122
|
after_create_save_success(**options)
|
122
123
|
else
|
@@ -17,6 +17,7 @@ module SnFoil
|
|
17
17
|
class_methods do
|
18
18
|
attr_reader :i_setup_destroy_hooks, :i_before_destroy_hooks, :i_after_destroy_hooks,
|
19
19
|
:i_after_destroy_success_hooks, :i_after_destroy_failure_hooks
|
20
|
+
|
20
21
|
def destroy(id:, entity: nil, **options)
|
21
22
|
new(entity).destroy(**options, id: id)
|
22
23
|
end
|
@@ -62,7 +63,7 @@ module SnFoil
|
|
62
63
|
options[:action] = :destroy
|
63
64
|
options = before_setup_destroy_object(**options)
|
64
65
|
options = setup_destroy_object(**options)
|
65
|
-
authorize(options[:object], options.fetch(:authorize
|
66
|
+
authorize(options[:object], options.fetch(:authorize, :destroy?), **options)
|
66
67
|
options = destroy_hooks(**options)
|
67
68
|
options[:object]
|
68
69
|
end
|
@@ -122,7 +123,7 @@ module SnFoil
|
|
122
123
|
def destroy_hooks(options)
|
123
124
|
options = before_destroy_save(options)
|
124
125
|
destroy_successful = options[:object].destroy
|
125
|
-
options
|
126
|
+
options[:object] = unwrap_object(options[:object])
|
126
127
|
options = if destroy_successful
|
127
128
|
after_destroy_save_success(options)
|
128
129
|
else
|
@@ -17,6 +17,7 @@ module SnFoil
|
|
17
17
|
class_methods do
|
18
18
|
attr_reader :i_setup_update_hooks, :i_before_update_hooks, :i_after_update_hooks,
|
19
19
|
:i_after_update_success_hooks, :i_after_update_failure_hooks
|
20
|
+
|
20
21
|
def update(id:, params:, entity: nil, **options)
|
21
22
|
new(entity).update(**options, id: id, params: params)
|
22
23
|
end
|
@@ -56,7 +57,7 @@ module SnFoil
|
|
56
57
|
raise ArgumentError, 'one of the following keywords is required: id, object' unless id || object
|
57
58
|
|
58
59
|
object = wrap_object(object || scope.resolve.find(id))
|
59
|
-
authorize(object, options.fetch(:authorize
|
60
|
+
authorize(object, options.fetch(:authorize, :update?), **options)
|
60
61
|
|
61
62
|
object.attributes = params
|
62
63
|
options.merge! object: object
|
@@ -66,7 +67,7 @@ module SnFoil
|
|
66
67
|
options[:action] = :update
|
67
68
|
options = before_setup_update_object(**options)
|
68
69
|
options = setup_update_object(**options)
|
69
|
-
authorize(options[:object], options.fetch(:authorize
|
70
|
+
authorize(options[:object], options.fetch(:authorize, :update?), **options)
|
70
71
|
options = update_hooks(**options)
|
71
72
|
options[:object]
|
72
73
|
end
|
@@ -126,7 +127,7 @@ module SnFoil
|
|
126
127
|
def update_hooks(options)
|
127
128
|
options = before_update_save(options)
|
128
129
|
update_successful = options[:object].save
|
129
|
-
options
|
130
|
+
options[:object] = unwrap_object(options[:object])
|
130
131
|
options = if update_successful
|
131
132
|
after_update_save_success(options)
|
132
133
|
else
|
data/lib/sn_foil/policy.rb
CHANGED
data/lib/sn_foil/searcher.rb
CHANGED
@@ -7,7 +7,7 @@ module SnFoil
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
9
|
class_methods do
|
10
|
-
attr_reader :i_model, :i_setup, :i_filters, :i_search_step
|
10
|
+
attr_reader :i_model, :i_setup, :i_filters, :i_search_step, :i_booleans
|
11
11
|
|
12
12
|
def model(klass = nil)
|
13
13
|
@i_model = klass
|
@@ -27,6 +27,11 @@ module SnFoil
|
|
27
27
|
unless: options[:unless]
|
28
28
|
}
|
29
29
|
end
|
30
|
+
|
31
|
+
def booleans(*fields)
|
32
|
+
@i_booleans ||= []
|
33
|
+
@i_booleans |= fields.map(&:to_sym)
|
34
|
+
end
|
30
35
|
end
|
31
36
|
|
32
37
|
def model
|
@@ -34,6 +39,7 @@ module SnFoil
|
|
34
39
|
end
|
35
40
|
|
36
41
|
attr_reader :scope
|
42
|
+
|
37
43
|
def initialize(scope: nil)
|
38
44
|
@scope = scope || model.all
|
39
45
|
end
|
@@ -55,6 +61,10 @@ module SnFoil
|
|
55
61
|
self.class.i_filters || []
|
56
62
|
end
|
57
63
|
|
64
|
+
def booleans
|
65
|
+
self.class.i_booleans || []
|
66
|
+
end
|
67
|
+
|
58
68
|
private
|
59
69
|
|
60
70
|
def apply_setup(filtered_scope, params)
|
@@ -90,15 +100,24 @@ module SnFoil
|
|
90
100
|
|
91
101
|
def transform_params_booleans(params)
|
92
102
|
params.map do |key, value|
|
93
|
-
value = if
|
94
|
-
|
95
|
-
elsif value == 'false'
|
96
|
-
false
|
103
|
+
value = if booleans.include?(key.to_sym)
|
104
|
+
value_to_boolean(value)
|
97
105
|
else
|
98
106
|
value
|
99
107
|
end
|
100
108
|
[key, value]
|
101
109
|
end.to_h
|
102
110
|
end
|
111
|
+
|
112
|
+
def value_to_boolean(value)
|
113
|
+
string_val = value.to_s
|
114
|
+
if value == true || %w[true 1].include?(string_val)
|
115
|
+
true
|
116
|
+
elsif value == false || %w[false 0].include?(string_val)
|
117
|
+
false
|
118
|
+
else
|
119
|
+
value
|
120
|
+
end
|
121
|
+
end
|
103
122
|
end
|
104
123
|
end
|
data/lib/sn_foil/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snfoil
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Howes
|
8
8
|
- Danny Murphy
|
9
|
+
- Cliff Campbell
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date:
|
13
|
+
date: 2021-08-12 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: activesupport
|
@@ -17,14 +18,14 @@ dependencies:
|
|
17
18
|
requirements:
|
18
19
|
- - ">="
|
19
20
|
- !ruby/object:Gem::Version
|
20
|
-
version: 5.2.
|
21
|
+
version: 5.2.6
|
21
22
|
type: :runtime
|
22
23
|
prerelease: false
|
23
24
|
version_requirements: !ruby/object:Gem::Requirement
|
24
25
|
requirements:
|
25
26
|
- - ">="
|
26
27
|
- !ruby/object:Gem::Version
|
27
|
-
version: 5.2.
|
28
|
+
version: 5.2.6
|
28
29
|
- !ruby/object:Gem::Dependency
|
29
30
|
name: logger
|
30
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,14 +60,14 @@ dependencies:
|
|
59
60
|
requirements:
|
60
61
|
- - "~>"
|
61
62
|
- !ruby/object:Gem::Version
|
62
|
-
version: '2.
|
63
|
+
version: '2.2'
|
63
64
|
type: :development
|
64
65
|
prerelease: false
|
65
66
|
version_requirements: !ruby/object:Gem::Requirement
|
66
67
|
requirements:
|
67
68
|
- - "~>"
|
68
69
|
- !ruby/object:Gem::Version
|
69
|
-
version: '2.
|
70
|
+
version: '2.2'
|
70
71
|
- !ruby/object:Gem::Dependency
|
71
72
|
name: dry-struct
|
72
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,14 +88,14 @@ dependencies:
|
|
87
88
|
requirements:
|
88
89
|
- - "~>"
|
89
90
|
- !ruby/object:Gem::Version
|
90
|
-
version: '3.
|
91
|
+
version: '3.9'
|
91
92
|
type: :development
|
92
93
|
prerelease: false
|
93
94
|
version_requirements: !ruby/object:Gem::Requirement
|
94
95
|
requirements:
|
95
96
|
- - "~>"
|
96
97
|
- !ruby/object:Gem::Version
|
97
|
-
version: '3.
|
98
|
+
version: '3.9'
|
98
99
|
- !ruby/object:Gem::Dependency
|
99
100
|
name: rake
|
100
101
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,32 +130,47 @@ dependencies:
|
|
129
130
|
requirements:
|
130
131
|
- - "~>"
|
131
132
|
- !ruby/object:Gem::Version
|
132
|
-
version:
|
133
|
+
version: '1.18'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - "~>"
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '1.18'
|
141
|
+
- !ruby/object:Gem::Dependency
|
142
|
+
name: rubocop-performance
|
143
|
+
requirement: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - "~>"
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '1.11'
|
133
148
|
type: :development
|
134
149
|
prerelease: false
|
135
150
|
version_requirements: !ruby/object:Gem::Requirement
|
136
151
|
requirements:
|
137
152
|
- - "~>"
|
138
153
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
154
|
+
version: '1.11'
|
140
155
|
- !ruby/object:Gem::Dependency
|
141
156
|
name: rubocop-rspec
|
142
157
|
requirement: !ruby/object:Gem::Requirement
|
143
158
|
requirements:
|
144
159
|
- - "~>"
|
145
160
|
- !ruby/object:Gem::Version
|
146
|
-
version:
|
161
|
+
version: '2.4'
|
147
162
|
type: :development
|
148
163
|
prerelease: false
|
149
164
|
version_requirements: !ruby/object:Gem::Requirement
|
150
165
|
requirements:
|
151
166
|
- - "~>"
|
152
167
|
- !ruby/object:Gem::Version
|
153
|
-
version:
|
168
|
+
version: '2.4'
|
154
169
|
description:
|
155
170
|
email:
|
156
171
|
- howeszy@gmail.com
|
157
172
|
- dmurph24@gmail.com
|
173
|
+
- cliffcampbell@hey.com
|
158
174
|
executables: []
|
159
175
|
extensions: []
|
160
176
|
extra_rdoc_files: []
|
@@ -178,7 +194,7 @@ files:
|
|
178
194
|
- lib/sn_foil/policy.rb
|
179
195
|
- lib/sn_foil/searcher.rb
|
180
196
|
- lib/sn_foil/version.rb
|
181
|
-
homepage: https://github.com/
|
197
|
+
homepage: https://github.com/limited-effort/snfoil
|
182
198
|
licenses:
|
183
199
|
- MIT
|
184
200
|
metadata: {}
|
@@ -190,14 +206,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
190
206
|
requirements:
|
191
207
|
- - ">="
|
192
208
|
- !ruby/object:Gem::Version
|
193
|
-
version:
|
209
|
+
version: 2.5.0
|
194
210
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
195
211
|
requirements:
|
196
212
|
- - ">="
|
197
213
|
- !ruby/object:Gem::Version
|
198
214
|
version: '0'
|
199
215
|
requirements: []
|
200
|
-
rubygems_version: 3.
|
216
|
+
rubygems_version: 3.1.6
|
201
217
|
signing_key:
|
202
218
|
specification_version: 4
|
203
219
|
summary: A boilerplate gem for providing basic contexts
|