rails-rapido 0.9.0 → 0.9.5

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
  SHA256:
3
- metadata.gz: e3eca4d11b378281f46d55bdcd604e5efbd73a27b80a501d97274f69090e90c0
4
- data.tar.gz: a0a53770a222728295abbe81b865b9721e4155af287c2f3a27def239cfd1fb12
3
+ metadata.gz: 8ad59d38c8d9c50021b6be12a144491e17d2025040f65c7714537ebe9831cf8e
4
+ data.tar.gz: b45ee3ef697c15438f7295704bcb4b0266a22612a9e59ddfb2c5f8e1c37a25c9
5
5
  SHA512:
6
- metadata.gz: '092a6bae662b3b92f90d135df192c33cee3da0617b21a2d5fabe0a20d9d2bb8c5f70a4b8fe9f431ee10599d2a8c05302aae2439332392c66dbdd2217ef6b2402'
7
- data.tar.gz: 8d6decc054b2d78524363e33817dc75dadd5a67409ac833d316423e89d8945d4d299ccbcb3a151d0c4df01f2baec1b68eb856a4c82a7953801c06b138c94eb1e
6
+ metadata.gz: 7bed2d6715e48d291343ae9dd18baed0feacbf9013372e518360c0df2ae0c02749f5b908d16de92756df30c2c3d2c889bfa91043def6571ce1127774e7c40b6c
7
+ data.tar.gz: '019ef8a8ff99a1c00a03e6ac395f435ee7ca96f1059afe2ef84b4ca1d0059703b0c8fbf05dd6f1ba3f4f10aed828902b70031f0ddae47dbf24ebf2e35ae47b63'
data/.rubocop.yml CHANGED
@@ -1,124 +1,431 @@
1
+ # Continue here: https://raw.githubusercontent.com/rubocop-hq/rubocop/master/config/default.yml
2
+ # TODO: Skipped rails or naming or style
3
+
1
4
  AllCops:
2
- TargetRubyVersion: 2.3
3
- # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
4
- # to ignore them, so only the ones explicitly set in this file are enabled.
5
- DisabledByDefault: true
6
5
  Exclude:
7
- - '**/templates/**/*'
8
- - '**/vendor/**/*'
9
- - 'actionpack/lib/action_dispatch/journey/parser.rb'
6
+ - 'node_modules/**/*'
7
+ - 'vendor/**/*'
8
+ - '.git/**/*'
9
+ - 'db/**/*'
10
+ - 'lib/tasks/cucumber.rake'
11
+ - 'config/routes.rb'
12
+ - 'features/**/*'
13
+ EnabledByDefault: false
14
+ DisabledByDefault: true
15
+
16
+ require: rubocop-performance
17
+
18
+ Bundler/DuplicatedGem:
19
+ Enabled: true
20
+
21
+ Bundler/InsecureProtocolSource:
22
+ Enabled: true
23
+
24
+ Bundler/OrderedGems:
25
+ Enabled: true
26
+
27
+ Gemspec/DuplicatedAssignment:
28
+ Enabled: true
29
+
30
+ Gemspec/OrderedDependencies:
31
+ Enabled: true
10
32
 
11
- # Prefer &&/|| over and/or.
12
- Style/AndOr:
33
+ Gemspec/RequiredRubyVersion:
13
34
  Enabled: true
14
35
 
15
- # Do not use braces for hash literals when they are the last argument of a
16
- # method call.
17
- Style/BracesAroundHashParameters:
36
+ Layout/BlockEndNewline:
18
37
  Enabled: true
19
38
 
20
- # Align `when` with `case`.
21
- Style/CaseIndentation:
39
+ Layout/ClassStructure:
22
40
  Enabled: true
23
41
 
24
- # Align comments with method definitions.
25
- Style/CommentIndentation:
42
+ Layout/ClosingParenthesisIndentation:
26
43
  Enabled: true
27
44
 
28
- # No extra empty lines.
29
- Style/EmptyLines:
45
+ Layout/ConditionPosition:
30
46
  Enabled: true
31
47
 
32
- # In a regular class definition, no empty lines around the body.
33
- Style/EmptyLinesAroundClassBody:
48
+ Layout/DefEndAlignment:
34
49
  Enabled: true
35
50
 
36
- # In a regular method definition, no empty lines around the body.
37
- Style/EmptyLinesAroundMethodBody:
51
+ Layout/ElseAlignment:
38
52
  Enabled: true
39
53
 
40
- # In a regular module definition, no empty lines around the body.
41
- Style/EmptyLinesAroundModuleBody:
54
+ Layout/EmptyLineBetweenDefs:
42
55
  Enabled: true
43
56
 
44
- # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
45
- Style/HashSyntax:
57
+ Layout/EmptyLines:
46
58
  Enabled: true
47
59
 
48
- # Method definitions after `private` or `protected` isolated calls need one
49
- # extra level of indentation.
50
- Style/IndentationConsistency:
60
+ Layout/EmptyLinesAroundAccessModifier:
51
61
  Enabled: true
52
- EnforcedStyle: rails
53
62
 
54
- # Two spaces, no tabs (for indentation).
55
- Style/IndentationWidth:
63
+ Layout/EndAlignment:
56
64
  Enabled: true
57
65
 
58
- Style/SpaceAfterColon:
66
+ Layout/EndOfLine:
59
67
  Enabled: true
60
68
 
61
- Style/SpaceAfterComma:
69
+ Layout/EmptyLinesAroundArguments:
62
70
  Enabled: true
63
71
 
64
- Style/SpaceAroundEqualsInParameterDefault:
72
+ Layout/IndentationWidth:
65
73
  Enabled: true
66
74
 
67
- Style/SpaceAroundKeyword:
75
+ Layout/InitialIndentation:
68
76
  Enabled: true
69
77
 
70
- Style/SpaceAroundOperators:
78
+ Layout/LeadingEmptyLines:
71
79
  Enabled: true
72
80
 
73
- Style/SpaceBeforeFirstArg:
74
- Enabled: true
81
+ Layout/SpaceAfterColon:
82
+ Enabled: true
83
+
84
+ Layout/SpaceAfterComma:
85
+ Enabled: true
86
+
87
+ Layout/SpaceAfterNot:
88
+ Enabled: true
89
+
90
+ Layout/SpaceAfterSemicolon:
91
+ Enabled: true
92
+
93
+ Layout/SpaceAroundEqualsInParameterDefault:
94
+ Enabled: true
95
+
96
+ Layout/SpaceAroundKeyword:
97
+ Enabled: true
98
+
99
+ Layout/SpaceBeforeComma:
100
+ Enabled: true
101
+
102
+ Layout/SpaceInsideStringInterpolation:
103
+ Enabled: true
104
+
105
+ Layout/IndentationStyle:
106
+ Enabled: true
107
+
108
+ Layout/TrailingEmptyLines:
109
+ Enabled: true
110
+
111
+ Layout/TrailingWhitespace:
112
+ Enabled: true
113
+
114
+ Lint/AssignmentInCondition:
115
+ Enabled: true
116
+
117
+ Lint/BooleanSymbol:
118
+ Enabled: true
119
+
120
+ Lint/CircularArgumentReference:
121
+ Enabled: true
122
+
123
+ Lint/Debugger:
124
+ Enabled: true
125
+
126
+ Lint/DuplicateCaseCondition:
127
+ Enabled: true
128
+
129
+ Lint/DuplicateMethods:
130
+ Enabled: true
131
+
132
+ Lint/DuplicateHashKey:
133
+ Enabled: true
134
+
135
+ Lint/EachWithObjectArgument:
136
+ Enabled: true
137
+
138
+ Lint/ElseLayout:
139
+ Enabled: true
75
140
 
76
- # Defining a method with parameters needs parentheses.
77
- Style/MethodDefParentheses:
141
+ Lint/EmptyEnsure:
78
142
  Enabled: true
79
143
 
80
- # Use `foo {}` not `foo{}`.
81
- Style/SpaceBeforeBlockBraces:
144
+ Lint/EmptyExpression:
82
145
  Enabled: true
83
146
 
84
- # Use `foo { bar }` not `foo {bar}`.
85
- Style/SpaceInsideBlockBraces:
147
+ Lint/EmptyInterpolation:
86
148
  Enabled: true
87
149
 
88
- # Use `{ a: 1 }` not `{a:1}`.
89
- Style/SpaceInsideHashLiteralBraces:
150
+ Lint/EmptyWhen:
90
151
  Enabled: true
91
152
 
92
- Style/SpaceInsideParens:
153
+ Lint/EnsureReturn:
93
154
  Enabled: true
94
155
 
95
- # Check quotes usage according to lint rule below.
96
- Style/StringLiterals:
156
+ Lint/FloatOutOfRange:
97
157
  Enabled: true
98
- EnforcedStyle: single_quotes
99
158
 
100
- # Detect hard tabs, no hard tabs.
101
- Style/Tab:
159
+ Lint/FormatParameterMismatch:
102
160
  Enabled: true
103
161
 
104
- # Blank lines should not have any spaces.
105
- Style/TrailingBlankLines:
162
+ Lint/SuppressedException:
106
163
  Enabled: true
107
164
 
108
- # No trailing whitespace.
109
- Style/TrailingWhitespace:
165
+ Lint/ImplicitStringConcatenation:
110
166
  Enabled: true
111
167
 
112
- # Use quotes for string literals when they are enough.
113
- Style/UnneededPercentQ:
168
+ Lint/IneffectiveAccessModifier:
114
169
  Enabled: true
115
170
 
116
- # Align `end` with the matching keyword or starting expression except for
117
- # assignments, where it should be aligned with the LHS.
118
- Lint/EndAlignment:
171
+ Lint/InheritException:
172
+ Enabled: true
173
+
174
+ Lint/InterpolationCheck:
175
+ Enabled: true
176
+
177
+ Lint/LiteralAsCondition:
178
+ Enabled: true
179
+
180
+ Lint/LiteralInInterpolation:
181
+ Enabled: true
182
+
183
+ Lint/Loop:
184
+ Enabled: true
185
+
186
+ Lint/MissingCopEnableDirective:
187
+ Enabled: true
188
+
189
+ Lint/MultipleComparison:
190
+ Enabled: true
191
+
192
+ Lint/NestedMethodDefinition:
193
+ Enabled: true
194
+
195
+ Lint/NextWithoutAccumulator:
196
+ Enabled: true
197
+
198
+ Lint/NonLocalExitFromIterator:
199
+ Enabled: true
200
+
201
+ # This caused too much confusion.
202
+ Lint/NumberConversion:
203
+ Enabled: false
204
+
205
+ Lint/ParenthesesAsGroupedExpression:
206
+ Enabled: true
207
+
208
+ Lint/PercentStringArray:
209
+ Enabled: true
210
+
211
+ Lint/PercentSymbolArray:
212
+ Enabled: true
213
+
214
+ Lint/RandOne:
215
+ Enabled: true
216
+
217
+ Lint/RedundantWithIndex:
218
+ Enabled: true
219
+
220
+ Lint/RedundantWithObject:
221
+ Enabled: true
222
+
223
+ Lint/RegexpAsCondition:
119
224
  Enabled: true
120
- EnforcedStyleAlignWith: variable
121
225
 
122
- # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
123
226
  Lint/RequireParentheses:
124
227
  Enabled: true
228
+
229
+ Lint/RescueException:
230
+ Enabled: true
231
+
232
+ Lint/RescueType:
233
+ Enabled: true
234
+
235
+ Lint/ReturnInVoidContext:
236
+ Enabled: true
237
+
238
+ Lint/SafeNavigationChain:
239
+ Enabled: true
240
+
241
+ Lint/SafeNavigationConsistency:
242
+ Enabled: true
243
+
244
+ Lint/ShadowedArgument:
245
+ Enabled: true
246
+
247
+ Lint/ShadowedException:
248
+ Enabled: true
249
+
250
+ Lint/ShadowingOuterLocalVariable:
251
+ Enabled: true
252
+
253
+ Lint/RedundantStringCoercion:
254
+ Enabled: true
255
+
256
+ Lint/Syntax:
257
+ Enabled: true
258
+
259
+ Lint/UnderscorePrefixedVariableName:
260
+ Enabled: true
261
+
262
+ Lint/UnifiedInteger:
263
+ Enabled: true
264
+
265
+ Lint/RedundantRequireStatement:
266
+ Enabled: true
267
+
268
+ Lint/RedundantSplatExpansion:
269
+ Enabled: true
270
+
271
+ Lint/UnreachableCode:
272
+ Enabled: true
273
+
274
+ Lint/UnusedBlockArgument:
275
+ Enabled: true
276
+
277
+ Lint/UnusedMethodArgument:
278
+ Enabled: true
279
+
280
+ Lint/UselessAccessModifier:
281
+ Enabled: true
282
+
283
+ Lint/UselessAssignment:
284
+ Enabled: true
285
+
286
+ Lint/BinaryOperatorWithIdenticalOperands:
287
+ Enabled: true
288
+
289
+ Lint/UselessElseWithoutRescue:
290
+ Enabled: true
291
+
292
+ Lint/UselessSetterCall:
293
+ Enabled: true
294
+
295
+ Lint/Void:
296
+ Enabled: true
297
+
298
+ Metrics/AbcSize:
299
+ Enabled: true
300
+ Max: 150
301
+
302
+ Metrics/BlockLength:
303
+ Enabled: true
304
+ Max: 100
305
+
306
+ Metrics/BlockNesting:
307
+ Enabled: true
308
+ Max: 3
309
+
310
+ Metrics/ClassLength:
311
+ Description: 'Avoid long classes'
312
+ Enabled: true
313
+ Max: 250
314
+
315
+ Metrics/CyclomaticComplexity:
316
+ Enabled: true
317
+ Max: 12
318
+
319
+ Layout/LineLength:
320
+ Enabled: true
321
+ Max: 200
322
+
323
+ Metrics/MethodLength:
324
+ Description: 'Avoid long methods.'
325
+ Enabled: true
326
+ Max: 30
327
+
328
+ Metrics/ModuleLength:
329
+ Description: 'Avoid long modules.'
330
+ Enabled: true
331
+ Max: 250
332
+
333
+ Metrics/ParameterLists:
334
+ Description: 'Avoid long parameter lists.'
335
+ Enabled: true
336
+ Max: 100
337
+
338
+ Metrics/PerceivedComplexity:
339
+ Enabled: true
340
+ Max: 15
341
+
342
+ Performance/Caller:
343
+ Enabled: true
344
+
345
+ Performance/Casecmp:
346
+ Enabled: true
347
+
348
+ # TODO: Re-enable
349
+ Performance/ChainArrayAllocation:
350
+ Enabled: false
351
+
352
+ Performance/CompareWithBlock:
353
+ Enabled: true
354
+
355
+ Performance/Count:
356
+ Enabled: true
357
+
358
+ Performance/Detect:
359
+ Enabled: true
360
+
361
+ Performance/DoubleStartEndWith:
362
+ Enabled: true
363
+
364
+ Performance/EndWith:
365
+ Enabled: true
366
+
367
+ Performance/FixedSize:
368
+ Enabled: true
369
+
370
+ Performance/FlatMap:
371
+ Enabled: true
372
+
373
+ Performance/InefficientHashSearch:
374
+ Enabled: true
375
+
376
+ Performance/RangeInclude:
377
+ Enabled: true
378
+
379
+ Performance/RedundantBlockCall:
380
+ Enabled: true
381
+
382
+ Performance/RedundantMatch:
383
+ Enabled: true
384
+
385
+ Performance/RedundantMerge:
386
+ Enabled: true
387
+
388
+ Style/RedundantSortBy:
389
+ Enabled: true
390
+
391
+ Performance/RegexpMatch:
392
+ Enabled: true
393
+
394
+ Performance/ReverseEach:
395
+ Enabled: true
396
+
397
+ Style/Sample:
398
+ Enabled: true
399
+
400
+ Performance/Size:
401
+ Enabled: true
402
+
403
+ Performance/StartWith:
404
+ Enabled: true
405
+
406
+ Performance/StringReplacement:
407
+ Enabled: true
408
+
409
+ Performance/TimesMap:
410
+ Enabled: true
411
+
412
+ Performance/UnfreezeString:
413
+ Enabled: true
414
+
415
+ Style/RedundantSort:
416
+ Enabled: true
417
+
418
+ Security/Eval:
419
+ Enabled: true
420
+
421
+ Security/JSONLoad:
422
+ Enabled: true
423
+
424
+ Security/MarshalLoad:
425
+ Enabled: true
426
+
427
+ Security/Open:
428
+ Enabled: true
429
+
430
+ Security/YAMLLoad:
431
+ Enabled: true
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.5
1
+ 2.7.2
data/README.md CHANGED
@@ -4,9 +4,67 @@
4
4
 
5
5
  Rapido is a simple, highly opinionated library that can be included into your Rails controllers to enforce standardized behavior and security.
6
6
 
7
+ ## Example
8
+
9
+ Below is a typical example of a class using Rapido. More examples are available in the [dummy application](https://github.com/starfighterheavy/rapido/tree/master/test/dummy).
10
+
11
+ ```ruby
12
+ # Create, Index: https://www.example.com/api/documents/
13
+ # Show, update, delete: https://www.example.com/api/documents/123
14
+
15
+ class DocumentsController < ApplicationController
16
+ include Rapido::ApiController
17
+
18
+ allow_if do
19
+ current_user.is_editor?
20
+ end
21
+
22
+ allow_only :create, :delete, :index, :show, :update
23
+
24
+ attr_permitted :file, :file_name, :category
25
+
26
+ belongs_to :user, getter: :current_user
27
+
28
+ present_with DocumentPresenter
29
+
30
+ present_collection_with DocumentCollectionPresenter, :query # Query could be a string supplied as a URL parameter to search documents by name.
31
+ end
32
+ ```
33
+
34
+ Another example where records are automatically retrieved from route parameters.
35
+
36
+ ```ruby
37
+ # Create, Index: https://www.example.com/api/documents/123/pages
38
+ # Show, update, delete: https://www.example.com/api/documents/123/pages/345
39
+
40
+ class PagesController < ApplicationController
41
+ include Rapido::ApiController
42
+
43
+ attr_permitted :contents, :page_number
44
+
45
+ belongs_to :document, owner: :current_user
46
+
47
+ present_with PagePresenter
48
+
49
+ present_collection_with PageCollectionPresenter
50
+ end
51
+ ```
52
+
7
53
  ## API
8
54
 
9
- #### `belongs_to`
55
+ ### `allow_if`
56
+
57
+ Accepts a method name as symbol or block. Method supplied or block must return true to allow the action to proceed, otherwise a status 401 is returned with no body.
58
+
59
+ ### `allow_only`
60
+
61
+ Accepts a list of symbols. These symbols specify the controller actions that are allowed for this controller.
62
+
63
+ ### `attr_permitted`
64
+
65
+ Accepts a list of symbols. These symbols specify the attributes that are supplied to StrongParameters as permitted parameters in `create` and `update` actions.
66
+
67
+ ### `belongs_to`
10
68
 
11
69
  Specifies the owner of the resource. For example, if many `Post` belonged to `User`, then in the `PostsController`, the following would be included: `belongs_to :user` and `Post` would be retrieved like so:
12
70
 
@@ -48,41 +106,56 @@ Default `[singular owner name]_id`. Specifies the param used as the owner's fore
48
106
 
49
107
  `User.find(params[:author_id]).posts.find(params[:id])`.
50
108
 
51
- #### `lookup_param`
109
+ ### `lookup_param`
52
110
 
53
111
  Specifies the param used to retrieve the resource. For example, if `Post` belongs to `User`, then in the `PostsController` if `lookup_param :token` is supplied, then the post would be retrieved like so:
54
112
 
55
113
  `User.find_by(params[:id]).posts.find_by(token: params[:token])`.
56
114
 
57
- #### `presented_by`
115
+ ### `present_with`
58
116
 
59
117
  Specifies the class that will present the resource. This class must accept the resource as the only parameter at initialization, and respond to the `as_json` for output when used with the `Rapido::ApiController`.
60
118
 
61
119
  For example, if `params` contained a `:filter` parameter which should be used by the presenter , then the following would work:
62
120
 
63
- `presented_by WidgetsPresenter, :filter`
121
+ `present_with WidgetsPresenter, :filter`
64
122
 
65
123
  The `initialize` method of the presenter should be structured as such:
66
124
 
67
125
  `def initialize(widgets, filter = nil)`
68
126
 
69
- #### `collection_presented_by`
127
+ ### `present_collection_with`
70
128
 
71
129
  Specifies the class that will present a collection of resources, as in the index method. Similar to `presented_by`, the class must accept the resource collection as the only argument at initialization, and respond to `as_json` for output when used with the `Rapido::ApiController`. The `collection_presented_by` can also accept a list of arguments, as symbols, that should be pulled from the `params` hash and passed to presenter class at initialization as optional argments.
72
130
 
73
- Collection presenters can also be provided args, similar to `presented_by`
131
+ Collection presenters can also be provided args, similar to `present_with`
74
132
 
75
- #### `attr_permitted`
133
+ ### `permit_no_params!`
76
134
 
77
- Accepts a list of symbols. These symbols specify the attributes that are supplied to StrongParameters as permitted parameters in `create` and `update` actions.
135
+ This will disallow any parameters in `create` and `update` actions.
78
136
 
79
- #### `permit_no_params!`
137
+ ## Filters
80
138
 
81
- This will disallow any parameters in `create` and `update` actions.
139
+ The following filters are available to override, similar to the standard Rails action filters.
140
+
141
+ #### Create
142
+
143
+ * before_build
144
+ * before_create
145
+ * after_create_success
146
+ * after_create_failure
147
+
148
+ #### Destroy
149
+
150
+ * before_destroy
151
+ * after_destroy_success
82
152
 
83
- ## Notes
153
+ #### Update
84
154
 
85
- Authentication & AppController functionality will be deprecated in v0.6 and removed in v1.0. With the 1.0 release, Rapido will remove all functionality that is not strictly oriented to streamlining API Controller development and security.
155
+ * before_assign_attributes
156
+ * before_updat
157
+ * after_update_success
158
+ * after_update_failure
86
159
 
87
160
  ## Development
88
161
 
@@ -18,24 +18,49 @@ module Rapido
18
18
  end
19
19
 
20
20
  before_action :permit_only_allowed_actions
21
+
22
+ before_action :permit_only_if
21
23
  end
22
24
 
23
25
  def index
24
- render json: present_resource_collection(resource_collection)
26
+ return if performed?
27
+ render json: resource_collection_presenter
25
28
  end
26
29
 
27
30
  def show
28
- render json: present_resource(resource)
31
+ return if performed?
32
+ if request.format.to_sym == :json
33
+ if(params["filename"])
34
+ send_data resource_presenter.as_json.to_json, filename: params["filename"]
35
+ else
36
+ render json: resource_presenter
37
+ end
38
+ elsif request.format.to_sym == :xml
39
+ if(params["filename"])
40
+ send_data resource_presenter.to_xml, filename: params["filename"]
41
+ else
42
+ render xml: resource_presenter
43
+ end
44
+ elsif request.format.to_sym == :csv
45
+ if(params["filename"])
46
+ send_data resource_presenter.to_csv, filename: params["filename"]
47
+ else
48
+ render plain: resource_presenter.send("to_csv")
49
+ end
50
+ else
51
+ render json: resource_presenter
52
+ end
29
53
  end
30
54
 
31
55
  def create
56
+ return if performed?
32
57
  before_build
33
58
  new_resource = build_resource(resource_params)
34
59
  before_create(new_resource)
35
60
  if new_resource.save
36
61
  after_create_success(new_resource)
37
62
  return if performed?
38
- render json: present_resource(new_resource), status: :created
63
+ render json: resource_presenter(new_resource), status: :created
39
64
  else
40
65
  after_create_failure(new_resource)
41
66
  return if performed?
@@ -44,7 +69,8 @@ module Rapido
44
69
  end
45
70
 
46
71
  def destroy
47
- resource_before_destruction = present_resource(resource)
72
+ return if performed?
73
+ resource_before_destruction = resource_presenter
48
74
  before_destroy
49
75
  resource.destroy
50
76
  after_destroy_success
@@ -53,13 +79,14 @@ module Rapido
53
79
  end
54
80
 
55
81
  def update
82
+ return if performed?
56
83
  before_assign_attributes
57
84
  resource.assign_attributes(resource_params)
58
85
  before_update
59
86
  if resource.save
60
87
  after_update_success
61
88
  return if performed?
62
- render json: present_resource(resource)
89
+ render json: resource_presenter
63
90
  else
64
91
  after_update_failure
65
92
  return if performed?
@@ -69,52 +96,71 @@ module Rapido
69
96
 
70
97
  private
71
98
 
72
- def after_create_failure(new_resource)
73
- end
99
+ def after_create_failure(new_resource)
100
+ end
74
101
 
75
- def after_create_success(new_resource)
76
- end
102
+ def after_create_success(new_resource)
103
+ end
77
104
 
78
- def after_destroy_success
79
- end
105
+ def after_destroy_success
106
+ end
80
107
 
81
- def after_update_failure
82
- end
108
+ def after_update_failure
109
+ end
83
110
 
84
- def after_update_success
85
- end
111
+ def after_update_success
112
+ end
86
113
 
87
- def before_assign_attributes
88
- end
114
+ def before_assign_attributes
115
+ end
89
116
 
90
- def before_build
91
- end
117
+ def before_build
118
+ end
92
119
 
93
- def before_create(new_resource)
94
- end
120
+ def before_create(new_resource)
121
+ end
95
122
 
96
- def before_destroy
97
- end
123
+ def before_destroy
124
+ end
98
125
 
99
- def before_update
100
- end
126
+ def before_update
127
+ end
128
+
129
+ def permit_only_allowed_actions
130
+ return unless allowed_actions
131
+ head :unauthorized unless allowed_actions.include?(params[:action].to_sym)
132
+ end
101
133
 
102
- def permit_only_allowed_actions
103
- return unless allowed_actions
104
- head :unauthorized unless allowed_actions.include?(params[:action].to_sym)
134
+ def permit_only_if
135
+ if(allow_if)
136
+ unless (allow_if.is_a?(Symbol) ? send(allow_if) : instance_eval(&allow_if))
137
+ head :unauthorized
138
+ end
105
139
  end
140
+ end
106
141
 
107
- def present_resource(resource)
142
+ def resource_presenter(new_resource = nil)
143
+ @resource_presenter ||= begin
108
144
  args = presenter_args.nil? ? nil : presenter_args.map { |arg| params[arg] }
109
- return presenter.new(*[resource, *args]).as_json if presenter
110
- resource.to_h
145
+ if presenter
146
+ presenter.new(new_resource || resource, *args)
147
+ else
148
+ (new_resource || resource).to_h
149
+ end
111
150
  end
151
+ end
112
152
 
113
- def present_resource_collection(resource_collection)
153
+ def resource_collection_presenter
154
+ @resource_collection_presenter ||= begin
114
155
  args = collection_presenter_args.nil? ? nil : collection_presenter_args.map { |arg| params[arg] }
115
- return collection_presenter.new(*[resource_collection, *args]).as_json if collection_presenter
116
- return resource_collection.map { |r| presenter.new(r).as_json } if presenter
117
- resource_collection.map(&:to_h)
156
+ if collection_presenter
157
+ collection_presenter.new(resource_collection, *args)
158
+ elsif presenter
159
+ resource_collection.map { |r| presenter.new(r) }
160
+ else
161
+ resource_collection.map(&:to_h)
162
+ end
118
163
  end
164
+ end
119
165
  end
120
166
  end
@@ -28,6 +28,10 @@ module Rapido
28
28
  @allowed_actions = ary
29
29
  end
30
30
 
31
+ def allow_if(str = nil, &block)
32
+ @allow_if = str || block
33
+ end
34
+
31
35
  def attr_permitted(*ary)
32
36
  @resource_permitted_params = ary
33
37
  end
@@ -97,136 +101,140 @@ module Rapido
97
101
 
98
102
  private
99
103
 
100
- def allowed_actions
101
- setting(:allowed_actions)
102
- end
104
+ def allowed_actions
105
+ setting(:allowed_actions)
106
+ end
103
107
 
104
- def build_resource(params = {})
105
- return owner.send('build_' + resource_class_name, params) if setting(:has_one)
106
- return owner.send(resource_class_name.pluralize).build(params) if owner && owner.respond_to?(resource_class_name.pluralize)
107
- begin
108
- send(:build)
109
- rescue NoMethodError
110
- raise 'Rapido::Controller must belong to something that responds to build or define a build method'
111
- end
112
- end
108
+ def allow_if
109
+ setting(:allow_if)
110
+ end
113
111
 
114
- def collection_presenter
115
- setting(:collection_presenter)
112
+ def build_resource(params = {})
113
+ return owner.send('build_' + resource_class_name, params) if setting(:has_one)
114
+ return owner.send(resource_class_name.pluralize).build(params) if owner && owner.respond_to?(resource_class_name.pluralize)
115
+ begin
116
+ send(:build)
117
+ rescue NoMethodError => _e
118
+ raise 'Rapido::Controller must belong to something that responds to build or define a build method'
116
119
  end
120
+ end
117
121
 
118
- def collection_presenter_args
119
- setting(:collection_presenter_args)
120
- end
122
+ def collection_presenter
123
+ setting(:collection_presenter)
124
+ end
121
125
 
122
- def owner_class
123
- return nil unless setting(:owner_class)
124
- @owner_class ||= begin
125
- name = setting(:owner_class)
126
- name.to_s.camelize.constantize
127
- rescue NameError
128
- raise BadOwnerClassName, name
129
- end
130
- end
126
+ def collection_presenter_args
127
+ setting(:collection_presenter_args)
128
+ end
131
129
 
132
- def owner_class_name
133
- @owner_class_name ||= owner_class.to_s.underscore
130
+ def owner_class
131
+ return nil unless setting(:owner_class)
132
+ @owner_class ||= begin
133
+ name = setting(:owner_class)
134
+ name.to_s.camelize.constantize
135
+ rescue NameError
136
+ raise BadOwnerClassName, name
134
137
  end
138
+ end
135
139
 
136
- def owner_lookup_param
137
- @owner_lookup_param ||=
138
- setting(:owner_lookup_param).to_s
139
- end
140
+ def owner_class_name
141
+ @owner_class_name ||= owner_class.to_s.underscore
142
+ end
140
143
 
141
- def owner_lookup_field
142
- @owner_lookup_field ||=
143
- (setting(:owner_lookup_field) || owner_lookup_param).to_s
144
- end
144
+ def owner_lookup_param
145
+ @owner_lookup_param ||=
146
+ setting(:owner_lookup_param).to_s
147
+ end
145
148
 
146
- def owner
147
- @owner ||= begin
148
- if setting(:owner_getter)
149
- send(setting(:owner_getter))
150
- elsif setting(:owner_class)
151
- if setting(:owners_owner)
152
- base = send(setting(:owners_owner)).send(owner_class_name.pluralize)
153
- else
154
- base = owner_class
155
- end
156
- base.find_by!(owner_lookup_field => params[owner_lookup_param])
149
+ def owner_lookup_field
150
+ @owner_lookup_field ||=
151
+ (setting(:owner_lookup_field) || owner_lookup_param).to_s
152
+ end
153
+
154
+ def owner
155
+ @owner ||= begin
156
+ if setting(:owner_getter)
157
+ send(setting(:owner_getter))
158
+ elsif setting(:owner_class)
159
+ if setting(:owners_owner)
160
+ base = send(setting(:owners_owner)).send(owner_class_name.pluralize)
157
161
  else
158
- nil
162
+ base = owner_class
159
163
  end
160
- rescue ActiveRecord::RecordNotFound
161
- raise RecordNotFound
164
+ base.find_by!(owner_lookup_field => params[owner_lookup_param])
165
+ else
166
+ nil
162
167
  end
168
+ rescue ActiveRecord::RecordNotFound
169
+ raise RecordNotFound
163
170
  end
171
+ end
164
172
 
165
- def presenter
166
- setting(:presenter)
167
- end
173
+ def presenter
174
+ setting(:presenter)
175
+ end
168
176
 
169
- def presenter_args
170
- setting(:presenter_args)
171
- end
177
+ def presenter_args
178
+ setting(:presenter_args)
179
+ end
172
180
 
173
- def resource
174
- @resource ||= begin
175
- if setting(:has_one)
176
- owner.send(resource_class_name)
177
- elsif owner && owner.respond_to?(resource_class_name.pluralize)
178
- owner
179
- .send(resource_class_name.pluralize)
180
- .find_by!(resource_lookup_param => params[resource_lookup_param])
181
- else
182
- begin NoMethodError
183
- send(:find)
184
- rescue
185
- raise 'Rapido::Controller must belong to something that has many or has one of resource, or define a find method'
186
- end
181
+ def resource
182
+ @resource ||= begin
183
+ if setting(:has_one)
184
+ owner.send(resource_class_name)
185
+ elsif owner && owner.respond_to?(resource_class_name.pluralize)
186
+ owner
187
+ .send(resource_class_name.pluralize)
188
+ .find_by!(resource_lookup_param => params[resource_lookup_param])
189
+ else
190
+ begin
191
+ send(:find)
192
+ rescue NoMethodError => _e
193
+ raise 'Rapido::Controller must belong to something that has many or has one of resource, or define a find method'
187
194
  end
188
- rescue ActiveRecord::RecordNotFound
189
- raise RecordNotFound
190
195
  end
196
+ rescue ActiveRecord::RecordNotFound
197
+ raise RecordNotFound
191
198
  end
199
+ end
192
200
 
193
- def resource_class
194
- @resource_class ||= resource_class_name.to_s.camelize.constantize
195
- end
201
+ def resource_class
202
+ @resource_class ||= resource_class_name.to_s.camelize.constantize
203
+ end
196
204
 
197
- def resource_class_name
198
- self.class.resource_class_name
199
- end
205
+ def resource_class_name
206
+ self.class.resource_class_name
207
+ end
200
208
 
201
209
  # Todo: FIXME
202
- def resource_collection
203
- @resource_collection ||= begin
204
- if setting(:has_one)
205
- owner.send(resource_class_name)
206
- else
207
- owner.send(resource_class_name.pluralize)
208
- end
210
+ def resource_collection
211
+ @resource_collection ||= begin
212
+ if setting(:has_one)
213
+ owner.send(resource_class_name)
214
+ else
215
+ owner.send(resource_class_name.pluralize)
209
216
  end
210
217
  end
218
+ end
211
219
 
212
- def resource_lookup_param
213
- @resource_lookup_param ||=
214
- setting(:resource_lookup_param) || :id
215
- end
220
+ def resource_lookup_param
221
+ @resource_lookup_param ||=
222
+ setting(:resource_lookup_param) || :id
223
+ end
216
224
 
217
- def resource_permitted_params
218
- @resource_permitted_params ||=
219
- setting(:resource_permitted_params)
220
- end
225
+ def resource_permitted_params
226
+ @resource_permitted_params ||=
227
+ setting(:resource_permitted_params)
228
+ end
221
229
 
222
- def resource_params
223
- return {} if setting(:permit_no_params)
224
- base = params.require(resource_class_name)
225
- base.permit(resource_permitted_params)
226
- end
230
+ def resource_params
231
+ return {} if setting(:permit_no_params)
232
+ base = params.require(resource_class_name)
233
+ base.permit(resource_permitted_params)
234
+ end
227
235
 
228
- def setting(var)
229
- self.class.instance_variable_get("@#{var}")
230
- end
236
+ def setting(var)
237
+ self.class.instance_variable_get("@#{var}")
238
+ end
231
239
  end
232
240
  end
@@ -1,3 +1,3 @@
1
1
  module Rapido
2
- VERSION = '0.9.0'
2
+ VERSION = '0.9.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-rapido
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Kirst
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-02 00:00:00.000000000 Z
11
+ date: 2021-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -83,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
83
  - !ruby/object:Gem::Version
84
84
  version: '0'
85
85
  requirements: []
86
- rubygems_version: 3.0.3
86
+ rubygems_version: 3.1.4
87
87
  signing_key:
88
88
  specification_version: 4
89
89
  summary: Rails API Dryer-o