snfoil 0.8.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +201 -0
- data/README.md +95 -505
- data/docs/build-context.md +56 -0
- data/docs/create-context.md +109 -0
- data/docs/destroy-context.md +102 -0
- data/docs/index-context.md +70 -0
- data/docs/show-context.md +71 -0
- data/docs/update-context.md +107 -0
- data/lib/{sn_foil → snfoil}/adapters/orms/active_record.rb +14 -0
- data/lib/{sn_foil → snfoil}/adapters/orms/base_adapter.rb +14 -0
- data/lib/snfoil/crud/build_context.rb +49 -0
- data/lib/snfoil/crud/change_context.rb +48 -0
- data/lib/snfoil/crud/context.rb +41 -0
- data/lib/snfoil/crud/create_context.rb +45 -0
- data/lib/snfoil/crud/destroy_context.rb +57 -0
- data/lib/snfoil/crud/index_context.rb +46 -0
- data/lib/snfoil/crud/setup_context.rb +90 -0
- data/lib/snfoil/crud/show_context.rb +52 -0
- data/lib/snfoil/crud/update_context.rb +60 -0
- data/lib/snfoil/version.rb +19 -0
- data/lib/snfoil.rb +69 -0
- data/snfoil.gemspec +47 -0
- metadata +99 -32
- data/Rakefile +0 -4
- data/lib/sn_foil/context.rb +0 -24
- data/lib/sn_foil/contexts/build_context.rb +0 -68
- data/lib/sn_foil/contexts/change_context.rb +0 -101
- data/lib/sn_foil/contexts/create_context.rb +0 -158
- data/lib/sn_foil/contexts/destroy_context.rb +0 -165
- data/lib/sn_foil/contexts/index_context.rb +0 -64
- data/lib/sn_foil/contexts/setup_context.rb +0 -121
- data/lib/sn_foil/contexts/show_context.rb +0 -62
- data/lib/sn_foil/contexts/update_context.rb +0 -169
- data/lib/sn_foil/policy.rb +0 -55
- data/lib/sn_foil/searcher.rb +0 -123
- data/lib/sn_foil/version.rb +0 -5
- data/lib/sn_foil.rb +0 -49
data/README.md
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# SnFoil
|
2
2
|
|
3
|
-
|
3
|
+
![build](https://github.com/limited-effort/snfoil/actions/workflows/main.yml/badge.svg) [![maintainability](https://api.codeclimate.com/v1/badges/86e0b2490738e140f2e2/maintainability)](https://codeclimate.com/github/limited-effort/snfoil/maintainability)
|
4
4
|
|
5
|
-
|
5
|
+
SnFoil has been broken into smaller modules. This gem serves to combine the most common gems in the SnFoil family and add some additional CRUD behavior.
|
6
|
+
|
7
|
+
This gem only uses [contexts](https://github.com/limited-effort/snfoil-context), [policies](https://github.com/limited-effort/snfoil-policy), and [searchers](https://github.com/limited-effort/snfoil-searcher) but you can check out all our modules here:
|
8
|
+
- [Contexts](https://github.com/limited-effort/snfoil-context) - Pipelined Business Logic
|
9
|
+
- [Controllers](https://github.com/limited-effort/snfoil-controller) - Separate HTTP Logic
|
10
|
+
- [Policies](https://github.com/limited-effort/snfoil-policy) - Authorization Checks
|
11
|
+
- [Rails](https://github.com/limited-effort/snfoil-rails) - Ruby on Rails Fluff
|
12
|
+
- [Searchers](https://github.com/limited-effort/snfoil-searcher) - Intuitive Search Classes
|
6
13
|
|
7
14
|
## Installation
|
8
15
|
|
@@ -11,546 +18,129 @@ Add this line to your application's Gemfile:
|
|
11
18
|
```ruby
|
12
19
|
gem 'snfoil'
|
13
20
|
```
|
21
|
+
## Usage
|
14
22
|
|
15
|
-
|
23
|
+
### Contexts
|
16
24
|
|
17
|
-
|
25
|
+
There is where the magic of the original gem started. The idea was to make a pipleline of logic that you could "plug" into certain intervals at. You can find the [full documentation for contexts here](https://github.com/limited-effort/snfoil-context).
|
18
26
|
|
19
|
-
|
27
|
+
SnFoil adds six CRUD-centeric contexts prewired to get you off the ground as fast as possible. Each context sets up intervals for you, and generally follow the same pattern for calls: `setup`, `setup_<action>`, `before_<action>`, `after_<action>_success`, `after_<action>_failure`, and `after_<action>`. You can find more information about each by clicking their respective links.
|
28
|
+
- [SnFoil::CRUD::BuildContext](docs/build-context.md) - for setting up an object.
|
29
|
+
- [SnFoil::CRUD::CreateContext](docs/create-context.md) - for setting up and saving an object to a data source.
|
30
|
+
- [SnFoil::CRUD::DestroyContext](docs/destroy-context.md) - find and destroy an object
|
31
|
+
- [SnFoil::CRUD::IndexContext](docs/index-context.md) - query for objects
|
32
|
+
- [SnFoil::CRUD::ShowContext](docs/show-context.md) - find an object
|
33
|
+
- [SnFoil::CRUD::UpdateContext](docs/update-context.md) find and update an object
|
20
34
|
|
21
|
-
|
35
|
+
You can pick and choose which features you want to use by including the specific file
|
22
36
|
|
23
|
-
|
37
|
+
```ruby
|
38
|
+
require 'snfoil/crud/index_context'
|
39
|
+
require 'snfoil/crud/show_context'
|
24
40
|
|
41
|
+
class PeopleContext
|
42
|
+
include SnFoil::CRUD::IndexContext
|
43
|
+
include SnFoil::CRUD::ShowContext
|
44
|
+
|
45
|
+
# hooks and methods here
|
46
|
+
end
|
47
|
+
```
|
25
48
|
|
26
|
-
|
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
|
49
|
+
Or you can add all them in one go with `SnFoil::CRUD::Context`.
|
87
50
|
|
88
51
|
```ruby
|
89
|
-
|
90
|
-
# Commit business logic to internal process
|
91
|
-
def after_create_success(**options)
|
92
|
-
options = super
|
52
|
+
require 'snfoil/crud/context'
|
93
53
|
|
94
|
-
|
95
|
-
|
54
|
+
class PeopleContext
|
55
|
+
include SnFoil::CRUD::Context
|
96
56
|
|
97
|
-
|
57
|
+
# hooks and methods here
|
98
58
|
end
|
59
|
+
```
|
60
|
+
|
61
|
+
Each of the CRUD contexts allows a Searcher, Policy, and Model to be added to the class. These are there so each function of the CRUD context can proceed without a lot of bootstrap code.
|
99
62
|
|
100
|
-
|
101
|
-
|
102
|
-
options = super
|
63
|
+
#### Searchers
|
64
|
+
Any time a model is fetched, that process goes through a searcher. This ensures that authorization logic is always followed - lowering the likelyhood of entity/user getting access to a model they shouldn't
|
103
65
|
|
104
|
-
|
66
|
+
```ruby
|
67
|
+
class PeopleContext
|
68
|
+
include SnFoil::CRUD::Context
|
105
69
|
|
106
|
-
|
70
|
+
searcher PeopleSearcher
|
107
71
|
end
|
108
72
|
```
|
109
73
|
|
110
|
-
|
111
|
-
|
74
|
+
#### Policies
|
75
|
+
Policies serve two purposes:
|
76
|
+
- Authorization
|
77
|
+
- Scopes
|
78
|
+
|
79
|
+
Authorization is pretty self explainatory. It is the logic of whether or not an entity is allowed to perform an action.
|
112
80
|
|
113
|
-
|
81
|
+
Scopes are definition of data that an entity/user is allowed to access. While they are not required for SnFoil::Policies, they are required for SnFoil's CRUD helpers.
|
114
82
|
|
115
|
-
#### Example
|
116
|
-
Lets take the Method example and make it into hooks instead.
|
117
83
|
```ruby
|
118
|
-
|
119
|
-
|
120
|
-
call_webhook_for_model(options[:object])
|
121
|
-
options
|
122
|
-
end
|
84
|
+
class PeopleContext
|
85
|
+
include SnFoil::CRUD::Context
|
123
86
|
|
124
|
-
|
125
|
-
after_create_success do |options|
|
126
|
-
finalize_business_logic(options[:object])
|
127
|
-
options
|
87
|
+
policy PersonPolicy
|
128
88
|
end
|
89
|
+
```
|
90
|
+
|
91
|
+
#### Models
|
129
92
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
93
|
+
Models are just the entity that the primary action of the CRUD context operates on. Simply put, its the Model.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
class PeopleContext
|
97
|
+
include SnFoil::CRUD::Context
|
98
|
+
|
99
|
+
model Person
|
134
100
|
end
|
135
101
|
```
|
136
102
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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
|
103
|
+
### ORM Adapters
|
104
|
+
|
105
|
+
In order to be able to work with multiple data sources SnFoil allows you to create adapters for interacting with object. Adapters are just wrapper for your objects that add specific functionality needed by the base `SnFoil::CRUD` methods. SnFoil handles the wrapping and unwrapping for you under the hood.
|
106
|
+
|
107
|
+
We created an adapter for `ActiveRecord` for you, but you can also create your own by inheriting from `SnFoil::Adapters::ORMs::BaseAdapter`.
|
108
|
+
|
109
|
+
Just make sure your adapter defines the following methods:
|
110
|
+
- `new` - method to create a new datasource object. This should not commit to the data source
|
111
|
+
- `all` - method to grab all of a type from the data source
|
112
|
+
- `save` - method to commit an object to the data source
|
113
|
+
- `destroy` - method to remove an object from the data source
|
114
|
+
- `attributes=` - method for assigning a hash of attributes to the object
|
115
|
+
|
116
|
+
You can set your custom adapter by directly assigning it
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
SnFoil.orm = CustomAdapter
|
120
|
+
```
|
121
|
+
|
122
|
+
Or if you prefer an initializer style
|
538
123
|
|
124
|
+
```ruby
|
125
|
+
SnFoil.configure do |config|
|
126
|
+
config.orm = CustomAdapter
|
127
|
+
end
|
128
|
+
```
|
539
129
|
|
540
130
|
## Development
|
541
131
|
|
542
|
-
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
132
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
543
133
|
|
544
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and
|
134
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
545
135
|
|
546
136
|
## Contributing
|
547
137
|
|
548
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
138
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/limited-effort/snfoil. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/limited-effort/snfoil/blob/main/CODE_OF_CONDUCT.md).
|
549
139
|
|
550
140
|
## License
|
551
141
|
|
552
|
-
The gem is available as open source under the terms of the [
|
142
|
+
The gem is available as open source under the terms of the [Apache 2 License](https://opensource.org/licenses/Apache-2.0).
|
553
143
|
|
554
144
|
## Code of Conduct
|
555
145
|
|
556
|
-
Everyone interacting in the
|
146
|
+
Everyone interacting in the Snfoil::Context project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/limited-effort/snfoil/blob/main/CODE_OF_CONDUCT.md).
|