ducalis 0.5.5 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -1
- data/DOCUMENTATION.md +250 -198
- data/Gemfile.lock +5 -5
- data/README.md +13 -1
- data/lib/ducalis/cops/callbacks_activerecord.rb +12 -5
- data/lib/ducalis/cops/case_mapping.rb +9 -8
- data/lib/ducalis/cops/controllers_except.rb +6 -6
- data/lib/ducalis/cops/keyword_defaults.rb +4 -5
- data/lib/ducalis/cops/module_like_class.rb +4 -5
- data/lib/ducalis/cops/params_passing.rb +5 -5
- data/lib/ducalis/cops/possible_tap.rb +12 -11
- data/lib/ducalis/cops/preferable_methods.rb +11 -5
- data/lib/ducalis/cops/private_instance_assign.rb +11 -4
- data/lib/ducalis/cops/protected_scope_cop.rb +11 -11
- data/lib/ducalis/cops/raise_withour_error_class.rb +4 -5
- data/lib/ducalis/cops/regex_cop.rb +13 -8
- data/lib/ducalis/cops/rest_only_cop.rb +5 -4
- data/lib/ducalis/cops/rubocop_disable.rb +5 -4
- data/lib/ducalis/cops/strings_in_activerecords.rb +7 -6
- data/lib/ducalis/cops/uncommented_gem.rb +6 -5
- data/lib/ducalis/cops/useless_only.rb +16 -16
- data/lib/ducalis/documentation.rb +16 -7
- data/lib/ducalis/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a11daa74e66a48aa5dcf55449524a52ce95ccfe
|
4
|
+
data.tar.gz: be32ea0b59dcbaf77839929724d98ce64562407e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1d720cf2eb513ce4073c5ed10ab6c96314efa49e3d416a1ae55bdba86530b8362da4bd49717322a161b04bbad5d134b38fe62885b498873cc4aec8e1af9d83c
|
7
|
+
data.tar.gz: f81669117b7f2ddb1c29d536cbe70823c8f435a25e93f517c712ed6f387a9a6aec4f42db6e4460ed266151350e5873de06b3fb03c0a80e1ff321222c10ae44f1
|
data/.codeclimate.yml
CHANGED
data/DOCUMENTATION.md
CHANGED
@@ -1,33 +1,34 @@
|
|
1
1
|
## Ducalis::CallbacksActiverecord
|
2
2
|
|
3
|
-
Please, avoid using of callbacks for models. It's better to
|
3
|
+
Please, avoid using of callbacks for models. It's better to
|
4
|
+
keep models small ("dumb") and instead use "builder" classes
|
5
|
+
/ services: to construct new objects. You can read more
|
6
|
+
[here](https://medium.com/planet-arkency/a61fd75ab2d3).
|
4
7
|
|
5
|
-
![](https://placehold.it/
|
8
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises on ActiveRecord classes which contains callbacks
|
6
9
|
```ruby
|
7
10
|
|
8
|
-
class
|
11
|
+
class Product < ActiveRecord::Base
|
9
12
|
before_create :generate_code
|
10
13
|
end
|
11
14
|
|
12
15
|
```
|
13
16
|
|
14
|
-
![](https://placehold.it/
|
17
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores non-ActiveRecord classes which contains callbacks
|
15
18
|
```ruby
|
16
19
|
|
17
|
-
class
|
20
|
+
class Product < BasicProduct
|
18
21
|
before_create :generate_code
|
19
22
|
end
|
20
23
|
|
21
24
|
```
|
22
25
|
## Ducalis::CaseMapping
|
23
26
|
|
24
|
-
Try to avoid `case when` statements. You can replace it with a sequence
|
25
|
-
`if... elsif... elsif... else`. For cases where you need to choose
|
26
|
-
large number of possibilities, you can create a dictionary
|
27
|
-
to functions to call by `call`. It's nice to have
|
28
|
-
names, i.e.: `visit_`.
|
29
|
-
|
30
|
-
<details>
|
27
|
+
Try to avoid `case when` statements. You can replace it with a sequence
|
28
|
+
of `if... elsif... elsif... else`. For cases where you need to choose
|
29
|
+
from a large number of possibilities, you can create a dictionary
|
30
|
+
mapping case values to functions to call by `call`. It's nice to have
|
31
|
+
prefix for the method names, i.e.: `visit_`.
|
31
32
|
Usually `case when` statements are using for the next reasons:
|
32
33
|
|
33
34
|
I. Mapping between different values.
|
@@ -100,7 +101,7 @@ more complex, table-driven code is simpler than complicated logic, easier to
|
|
100
101
|
modify and more efficient.
|
101
102
|
</details>
|
102
103
|
|
103
|
-
![](https://placehold.it/
|
104
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises on case statements
|
104
105
|
```ruby
|
105
106
|
|
106
107
|
case grade
|
@@ -117,125 +118,136 @@ end
|
|
117
118
|
```
|
118
119
|
## Ducalis::ControllersExcept
|
119
120
|
|
120
|
-
Prefer to use `:only` over `:except` in controllers because it's more
|
121
|
+
Prefer to use `:only` over `:except` in controllers because it's more
|
122
|
+
explicit and will be easier to maintain for new developers.
|
121
123
|
|
122
|
-
![](https://placehold.it/
|
124
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for `before_filters` with `except` method as array
|
123
125
|
```ruby
|
124
126
|
|
125
|
-
class
|
126
|
-
before_filter :
|
127
|
+
class ProductsController < ApplicationController
|
128
|
+
before_filter :update_cost, except: [:index]
|
129
|
+
|
127
130
|
def index; end
|
128
131
|
def edit; end
|
132
|
+
|
129
133
|
private
|
130
|
-
|
134
|
+
|
135
|
+
def update_cost; end
|
131
136
|
end
|
132
137
|
|
133
138
|
```
|
134
139
|
|
135
|
-
![](https://placehold.it/
|
140
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for filters with many actions and only one `except` method
|
136
141
|
```ruby
|
137
142
|
|
138
|
-
class
|
139
|
-
before_filter :
|
143
|
+
class ProductsController < ApplicationController
|
144
|
+
before_filter :update_cost, :load_me, except: %i[edit]
|
145
|
+
|
140
146
|
def index; end
|
141
147
|
def edit; end
|
148
|
+
|
142
149
|
private
|
143
|
-
|
150
|
+
|
151
|
+
def update_cost; end
|
144
152
|
def load_me; end
|
145
153
|
end
|
146
154
|
|
147
155
|
```
|
148
156
|
|
149
|
-
![](https://placehold.it/
|
157
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores `before_filters` without arguments
|
150
158
|
```ruby
|
151
159
|
|
152
|
-
class
|
153
|
-
before_filter :
|
160
|
+
class ProductsController < ApplicationController
|
161
|
+
before_filter :update_cost
|
162
|
+
|
154
163
|
def index; end
|
164
|
+
|
155
165
|
private
|
156
|
-
|
166
|
+
|
167
|
+
def update_cost; end
|
157
168
|
end
|
158
169
|
|
159
170
|
```
|
160
171
|
## Ducalis::KeywordDefaults
|
161
172
|
|
162
|
-
Prefer to use keyword arguments for defaults. It increases readability
|
173
|
+
Prefer to use keyword arguments for defaults. It increases readability
|
174
|
+
and reduces ambiguities.
|
163
175
|
|
164
|
-
![](https://placehold.it/
|
176
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if method definition contains default values
|
165
177
|
```ruby
|
166
|
-
def
|
178
|
+
def calculate(step, index, dry = true); end
|
167
179
|
```
|
168
180
|
|
169
|
-
![](https://placehold.it/
|
181
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if class method definition contains default values
|
170
182
|
```ruby
|
171
|
-
def self.
|
183
|
+
def self.calculate(step, index, dry = true); end
|
172
184
|
```
|
173
185
|
|
174
|
-
![](https://placehold.it/
|
186
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores if method definition contains default values through keywords
|
175
187
|
```ruby
|
176
|
-
def
|
188
|
+
def calculate(step, index, dry: true); end
|
177
189
|
```
|
178
190
|
|
179
|
-
![](https://placehold.it/
|
191
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores for methods without arguments
|
180
192
|
```ruby
|
181
|
-
def
|
193
|
+
def calculate_amount; end
|
182
194
|
```
|
183
195
|
|
184
|
-
![](https://placehold.it/
|
196
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores for class methods without arguments
|
185
197
|
```ruby
|
186
|
-
def self.
|
198
|
+
def self.calculate_amount; end
|
187
199
|
```
|
188
200
|
## Ducalis::ModuleLikeClass
|
189
201
|
|
190
|
-
Seems like it will be better to define initialize and pass %<args>s
|
202
|
+
Seems like it will be better to define initialize and pass %<args>s
|
203
|
+
there instead of each method.
|
191
204
|
|
192
|
-
![](https://placehold.it/
|
205
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if class doesn't contain constructor but accept the same args
|
193
206
|
```ruby
|
194
207
|
|
195
|
-
class
|
196
|
-
|
208
|
+
class TaskJournal
|
197
209
|
def initialize(customer)
|
198
210
|
# ...
|
199
211
|
end
|
200
212
|
|
201
|
-
def approve(task, estimate,
|
213
|
+
def approve(task, estimate, options)
|
202
214
|
# ...
|
203
215
|
end
|
204
216
|
|
205
|
-
def decline(user, task, estimate,
|
217
|
+
def decline(user, task, estimate, details)
|
206
218
|
# ...
|
207
219
|
end
|
208
220
|
|
209
221
|
private
|
210
222
|
|
211
|
-
def
|
223
|
+
def log(record)
|
212
224
|
# ...
|
213
225
|
end
|
214
226
|
end
|
215
227
|
|
216
228
|
```
|
217
229
|
|
218
|
-
![](https://placehold.it/
|
230
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for class with only one public method with args
|
219
231
|
```ruby
|
220
232
|
|
221
|
-
class
|
233
|
+
class TaskJournal
|
222
234
|
def approve(task)
|
223
235
|
# ...
|
224
236
|
end
|
225
237
|
|
226
238
|
private
|
227
239
|
|
228
|
-
def
|
240
|
+
def log(record)
|
229
241
|
# ...
|
230
242
|
end
|
231
243
|
end
|
232
244
|
|
233
245
|
```
|
234
246
|
|
235
|
-
![](https://placehold.it/
|
247
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores classes with custom includes
|
236
248
|
```ruby
|
237
249
|
|
238
|
-
class
|
250
|
+
class TaskJournal
|
239
251
|
include Singleton
|
240
252
|
|
241
253
|
def approve(task)
|
@@ -245,27 +257,27 @@ end
|
|
245
257
|
|
246
258
|
```
|
247
259
|
|
248
|
-
![](https://placehold.it/
|
260
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores classes with inheritance
|
249
261
|
```ruby
|
250
262
|
|
251
|
-
class
|
263
|
+
class TaskJournal < BasicJournal
|
252
264
|
def approve(task)
|
253
265
|
# ...
|
254
266
|
end
|
255
267
|
|
256
268
|
private
|
257
269
|
|
258
|
-
def
|
270
|
+
def log(record)
|
259
271
|
# ...
|
260
272
|
end
|
261
273
|
end
|
262
274
|
|
263
275
|
```
|
264
276
|
|
265
|
-
![](https://placehold.it/
|
277
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores classes with one method and initializer
|
266
278
|
```ruby
|
267
279
|
|
268
|
-
class
|
280
|
+
class TaskJournal
|
269
281
|
def initialize(task)
|
270
282
|
# ...
|
271
283
|
end
|
@@ -278,79 +290,83 @@ end
|
|
278
290
|
```
|
279
291
|
## Ducalis::ParamsPassing
|
280
292
|
|
281
|
-
It's better to pass already preprocessed params hash to services. Or
|
282
|
-
`arcane` gem
|
293
|
+
It's better to pass already preprocessed params hash to services. Or
|
294
|
+
you can use `arcane` gem.
|
283
295
|
|
284
|
-
![](https://placehold.it/
|
296
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if user pass `params` as argument from controller
|
285
297
|
```ruby
|
286
298
|
|
287
|
-
class
|
299
|
+
class ProductsController < ApplicationController
|
288
300
|
def index
|
289
|
-
|
301
|
+
Record.new(params).log
|
290
302
|
end
|
291
303
|
end
|
292
304
|
|
293
305
|
```
|
294
306
|
|
295
|
-
![](https://placehold.it/
|
307
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if user pass `params` as any argument from controller
|
296
308
|
```ruby
|
297
309
|
|
298
|
-
class
|
310
|
+
class ProductsController < ApplicationController
|
299
311
|
def index
|
300
|
-
|
312
|
+
Record.new(first_arg, params).log
|
301
313
|
end
|
302
314
|
end
|
303
315
|
|
304
316
|
```
|
305
317
|
|
306
|
-
![](https://placehold.it/
|
318
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if user pass `params` as keyword argument from controller
|
307
319
|
```ruby
|
308
320
|
|
309
|
-
class
|
321
|
+
class ProductsController < ApplicationController
|
310
322
|
def index
|
311
|
-
|
323
|
+
Record.new(first_arg, any_name: params).log
|
312
324
|
end
|
313
325
|
end
|
314
326
|
|
315
327
|
```
|
316
328
|
|
317
|
-
![](https://placehold.it/
|
329
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores passing only one `params` field
|
318
330
|
```ruby
|
319
331
|
|
320
|
-
class
|
332
|
+
class ProductsController < ApplicationController
|
321
333
|
def index
|
322
|
-
|
334
|
+
Record.new(first_arg, params[:id]).log
|
323
335
|
end
|
324
336
|
end
|
325
337
|
|
326
338
|
```
|
327
339
|
|
328
|
-
![](https://placehold.it/
|
340
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores passing processed `params`
|
329
341
|
```ruby
|
330
342
|
|
331
|
-
class
|
343
|
+
class ProductsController < ApplicationController
|
332
344
|
def index
|
333
|
-
|
345
|
+
Record.new(first_arg, params.slice(:name)).log
|
334
346
|
end
|
335
347
|
end
|
336
348
|
|
337
349
|
```
|
338
350
|
|
339
|
-
![](https://placehold.it/
|
351
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores passing `params` from `arcane` gem
|
340
352
|
```ruby
|
341
353
|
|
342
|
-
class
|
354
|
+
class ProductsController < ApplicationController
|
343
355
|
def index
|
344
|
-
|
356
|
+
Record.new(params.for(Log).as(user).refine).log
|
345
357
|
end
|
346
358
|
end
|
347
359
|
|
348
360
|
```
|
349
361
|
## Ducalis::PossibleTap
|
350
362
|
|
351
|
-
Consider of using `.tap`, default ruby
|
363
|
+
Consider of using `.tap`, default ruby
|
364
|
+
[method](<https://apidock.com/ruby/Object/tap>)
|
365
|
+
which allows to replace intermediate variables with block, by this you
|
366
|
+
are limiting scope pollution and make scope more clear.
|
367
|
+
[Related article](<http://seejohncode.com/2012/01/02/ruby-tap-that/>).
|
352
368
|
|
353
|
-
![](https://placehold.it/
|
369
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for methods with scope variable return
|
354
370
|
```ruby
|
355
371
|
|
356
372
|
def load_group
|
@@ -361,7 +377,7 @@ end
|
|
361
377
|
|
362
378
|
```
|
363
379
|
|
364
|
-
![](https://placehold.it/
|
380
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for methods with instance variable changes and return
|
365
381
|
```ruby
|
366
382
|
|
367
383
|
def load_group
|
@@ -372,7 +388,7 @@ end
|
|
372
388
|
|
373
389
|
```
|
374
390
|
|
375
|
-
![](https://placehold.it/
|
391
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for methods with instance variable `||=` assign and return
|
376
392
|
```ruby
|
377
393
|
|
378
394
|
def define_roles
|
@@ -386,7 +402,7 @@ end
|
|
386
402
|
|
387
403
|
```
|
388
404
|
|
389
|
-
![](https://placehold.it/
|
405
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for methods which return call on scope variable
|
390
406
|
```ruby
|
391
407
|
|
392
408
|
def load_group
|
@@ -400,7 +416,7 @@ end
|
|
400
416
|
|
401
417
|
```
|
402
418
|
|
403
|
-
![](https://placehold.it/
|
419
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for methods which return instance variable but have scope vars
|
404
420
|
```ruby
|
405
421
|
|
406
422
|
def generate_file(file_name)
|
@@ -413,7 +429,7 @@ end
|
|
413
429
|
|
414
430
|
```
|
415
431
|
|
416
|
-
![](https://placehold.it/
|
432
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores empty methods
|
417
433
|
```ruby
|
418
434
|
|
419
435
|
def edit
|
@@ -421,7 +437,7 @@ end
|
|
421
437
|
|
422
438
|
```
|
423
439
|
|
424
|
-
![](https://placehold.it/
|
440
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores methods which body is just call
|
425
441
|
```ruby
|
426
442
|
|
427
443
|
def total_cost(cost_field)
|
@@ -430,7 +446,7 @@ end
|
|
430
446
|
|
431
447
|
```
|
432
448
|
|
433
|
-
![](https://placehold.it/
|
449
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores methods which return some statement
|
434
450
|
```ruby
|
435
451
|
|
436
452
|
def stop_terminated_employee
|
@@ -443,7 +459,7 @@ end
|
|
443
459
|
|
444
460
|
```
|
445
461
|
|
446
|
-
![](https://placehold.it/
|
462
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores methods which simply returns instance var without changes
|
447
463
|
```ruby
|
448
464
|
|
449
465
|
def employee
|
@@ -454,40 +470,48 @@ end
|
|
454
470
|
## Ducalis::PreferableMethods
|
455
471
|
|
456
472
|
Prefer to use %<alternative>s method instead of %<original>s because of
|
457
|
-
%<reason>s.
|
473
|
+
%<reason>s.
|
474
|
+
Dangerous methods are:
|
475
|
+
`delete_all`, `delete`.
|
458
476
|
|
459
|
-
![](https://placehold.it/
|
477
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for `delete` method calling
|
460
478
|
```ruby
|
461
479
|
User.where(id: 7).delete
|
462
480
|
```
|
463
481
|
|
464
|
-
![](https://placehold.it/
|
482
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores calling `delete` with symbol
|
465
483
|
```ruby
|
466
484
|
params.delete(:code)
|
467
485
|
```
|
468
486
|
|
469
|
-
![](https://placehold.it/
|
487
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores calling `delete` with string
|
470
488
|
```ruby
|
471
489
|
string.delete("-")
|
472
490
|
```
|
473
491
|
|
474
|
-
![](https://placehold.it/
|
492
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores calling `delete` with multiple args
|
475
493
|
```ruby
|
476
494
|
some.delete(1, header: [])
|
477
495
|
```
|
478
496
|
|
479
|
-
![](https://placehold.it/
|
497
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores calling `delete` on files-like variables
|
480
498
|
```ruby
|
481
499
|
tempfile.delete
|
482
500
|
```
|
483
501
|
## Ducalis::PrivateInstanceAssign
|
484
502
|
|
485
|
-
|
503
|
+
Don't use filters for setting instance variables, use them only for
|
504
|
+
changing application flow, such as redirecting if a user is not
|
505
|
+
authenticated. Controller instance variables are forming contract
|
506
|
+
between controller and view. Keeping instance variables defined in one
|
507
|
+
place makes it easier to: reason, refactor and remove old views, test
|
508
|
+
controllers and views, extract actions to new controllers, etc.
|
509
|
+
If you want to memoize variable, please, add underscore to the variable name start: `@_name`.
|
486
510
|
|
487
|
-
![](https://placehold.it/
|
511
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for assigning instance variables in controllers private methods
|
488
512
|
```ruby
|
489
513
|
|
490
|
-
class
|
514
|
+
class EmployeesController < ApplicationController
|
491
515
|
private
|
492
516
|
|
493
517
|
def load_employee
|
@@ -497,36 +521,36 @@ end
|
|
497
521
|
|
498
522
|
```
|
499
523
|
|
500
|
-
![](https://placehold.it/
|
524
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for memoization variables in controllers private methods
|
501
525
|
```ruby
|
502
526
|
|
503
|
-
class
|
527
|
+
class EmployeesController < ApplicationController
|
504
528
|
private
|
505
529
|
|
506
|
-
def
|
507
|
-
@
|
530
|
+
def catalog
|
531
|
+
@catalog ||= Catalog.new
|
508
532
|
end
|
509
533
|
end
|
510
534
|
|
511
535
|
```
|
512
536
|
|
513
|
-
![](https://placehold.it/
|
537
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores memoization variables in controllers private methods with _
|
514
538
|
```ruby
|
515
539
|
|
516
|
-
class
|
540
|
+
class EmployeesController < ApplicationController
|
517
541
|
private
|
518
542
|
|
519
|
-
def
|
520
|
-
@
|
543
|
+
def catalog
|
544
|
+
@_catalog ||= Catalog.new
|
521
545
|
end
|
522
546
|
end
|
523
547
|
|
524
548
|
```
|
525
549
|
|
526
|
-
![](https://placehold.it/
|
550
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores assigning instance variables in controllers public methods
|
527
551
|
```ruby
|
528
552
|
|
529
|
-
class
|
553
|
+
class EmployeesController < ApplicationController
|
530
554
|
def index
|
531
555
|
@employee = load_employee
|
532
556
|
end
|
@@ -541,37 +565,37 @@ end
|
|
541
565
|
```
|
542
566
|
## Ducalis::ProtectedScopeCop
|
543
567
|
|
544
|
-
Seems like you are using `find` on non-protected scope. Potentially it
|
545
|
-
lead to unauthorized access. It's better to call `find` on
|
546
|
-
scopes. Example:
|
568
|
+
Seems like you are using `find` on non-protected scope. Potentially it
|
569
|
+
could lead to unauthorized access. It's better to call `find` on
|
570
|
+
authorized resources scopes. Example:
|
547
571
|
|
548
|
-
```ruby
|
549
|
-
current_group.employees.find(params[:id])
|
550
|
-
# better then
|
551
|
-
Employee.find(params[:id])
|
552
|
-
```
|
572
|
+
```ruby
|
573
|
+
current_group.employees.find(params[:id])
|
574
|
+
# better then
|
575
|
+
Employee.find(params[:id])
|
576
|
+
```
|
553
577
|
|
554
|
-
![](https://placehold.it/
|
578
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if somewhere AR search was called on not protected scope
|
555
579
|
```ruby
|
556
580
|
Group.find(8)
|
557
581
|
```
|
558
582
|
|
559
|
-
![](https://placehold.it/
|
583
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if AR search was called even for chain of calls
|
560
584
|
```ruby
|
561
|
-
Group.includes(:
|
585
|
+
Group.includes(:profiles).find(8)
|
562
586
|
```
|
563
587
|
|
564
|
-
![](https://placehold.it/
|
588
|
+
![](https://placehold.it/10/f03c15/000000?text=+) ignores where statements and still raises error
|
565
589
|
```ruby
|
566
|
-
Group.includes(:
|
590
|
+
Group.includes(:profiles).where(name: "John").find(8)
|
567
591
|
```
|
568
592
|
|
569
|
-
![](https://placehold.it/
|
593
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores find method with passed block
|
570
594
|
```ruby
|
571
595
|
MAPPING.find { |x| x == 42 }
|
572
596
|
```
|
573
597
|
|
574
|
-
![](https://placehold.it/
|
598
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores find method with passed multiline block
|
575
599
|
```ruby
|
576
600
|
|
577
601
|
MAPPING.find do |x|
|
@@ -581,33 +605,37 @@ end
|
|
581
605
|
```
|
582
606
|
## Ducalis::RaiseWithourErrorClass
|
583
607
|
|
584
|
-
It's better to add exception class as raise argument. It will make
|
608
|
+
It's better to add exception class as raise argument. It will make
|
609
|
+
easier to catch and process it later.
|
585
610
|
|
586
|
-
![](https://placehold.it/
|
611
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises when `raise` called without exception class
|
587
612
|
```ruby
|
588
613
|
raise "Something went wrong"
|
589
614
|
```
|
590
615
|
|
591
|
-
![](https://placehold.it/
|
616
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores when `raise` called with exception class
|
592
617
|
```ruby
|
593
618
|
raise StandardError, "Something went wrong"
|
594
619
|
```
|
595
620
|
|
596
|
-
![](https://placehold.it/
|
621
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores when `raise` called with exception instance
|
597
622
|
```ruby
|
598
623
|
raise StandardError.new("Something went wrong")
|
599
624
|
```
|
600
625
|
## Ducalis::RegexCop
|
601
626
|
|
602
|
-
It's better to move regex to constants with example instead of direct
|
603
|
-
It will allow you to reuse this regex and provide instructions
|
627
|
+
It's better to move regex to constants with example instead of direct
|
628
|
+
using it. It will allow you to reuse this regex and provide instructions
|
629
|
+
for others.
|
604
630
|
|
605
631
|
```ruby
|
606
632
|
CONST_NAME = %<constant>s # "%<example>s"
|
607
633
|
%<fixed_string>s
|
608
634
|
```
|
635
|
+
Available regexes are:
|
636
|
+
`/[[:alnum:]]/`, `/[[:alpha:]]/`, `/[[:blank:]]/`, `/[[:cntrl:]]/`, `/[[:digit:]]/`, `/[[:graph:]]/`, `/[[:lower:]]/`, `/[[:print:]]/`, `/[[:punct:]]/`, `/[[:space:]]/`, `/[[:upper:]]/`, `/[[:xdigit:]]/`, `/[[:word:]]/`, `/[[:ascii:]]/`
|
609
637
|
|
610
|
-
![](https://placehold.it/
|
638
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises if somewhere in code used regex which is not moved to const
|
611
639
|
```ruby
|
612
640
|
|
613
641
|
name = "john"
|
@@ -615,7 +643,7 @@ puts "hi" if name =~ /john/
|
|
615
643
|
|
616
644
|
```
|
617
645
|
|
618
|
-
![](https://placehold.it/
|
646
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores matching constants
|
619
647
|
```ruby
|
620
648
|
|
621
649
|
REGEX = /john/
|
@@ -624,7 +652,7 @@ puts "hi" if name =~ REGEX
|
|
624
652
|
|
625
653
|
```
|
626
654
|
|
627
|
-
![](https://placehold.it/
|
655
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores named ruby constants
|
628
656
|
```ruby
|
629
657
|
|
630
658
|
name = "john"
|
@@ -632,7 +660,7 @@ puts "hi" if name =~ /[[:alpha:]]/
|
|
632
660
|
|
633
661
|
```
|
634
662
|
|
635
|
-
![](https://placehold.it/
|
663
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores dynamic regexs
|
636
664
|
```ruby
|
637
665
|
|
638
666
|
name = "john"
|
@@ -642,33 +670,35 @@ puts "hi" if name =~ /.{#{name.length}}/
|
|
642
670
|
## Ducalis::RestOnlyCop
|
643
671
|
|
644
672
|
It's better for controllers to stay adherent to REST:
|
645
|
-
http://jeromedalbert.com/how-dhh-organizes-his-rails-controllers/
|
673
|
+
http://jeromedalbert.com/how-dhh-organizes-his-rails-controllers/
|
646
674
|
|
647
|
-
![](https://placehold.it/
|
675
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for controllers with non-REST methods
|
648
676
|
```ruby
|
649
677
|
|
650
|
-
class
|
678
|
+
class ProductsController < ApplicationController
|
651
679
|
def index; end
|
652
|
-
def
|
680
|
+
def recalculate; end
|
653
681
|
end
|
654
682
|
|
655
683
|
```
|
656
684
|
|
657
|
-
![](https://placehold.it/
|
685
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores controllers with private non-REST methods
|
658
686
|
```ruby
|
659
687
|
|
660
|
-
class
|
688
|
+
class ProductsController < ApplicationController
|
661
689
|
def index; end
|
690
|
+
|
662
691
|
private
|
663
|
-
|
692
|
+
|
693
|
+
def recalculate; end
|
664
694
|
end
|
665
695
|
|
666
696
|
```
|
667
697
|
|
668
|
-
![](https://placehold.it/
|
698
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores controllers with only REST methods
|
669
699
|
```ruby
|
670
700
|
|
671
|
-
class
|
701
|
+
class ProductsController < ApplicationController
|
672
702
|
def index; end
|
673
703
|
def show; end
|
674
704
|
def new; end
|
@@ -680,43 +710,42 @@ end
|
|
680
710
|
|
681
711
|
```
|
682
712
|
|
683
|
-
![](https://placehold.it/
|
713
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores non-controllers with non-REST methods
|
684
714
|
```ruby
|
685
715
|
|
686
|
-
class
|
716
|
+
class PriceStore
|
687
717
|
def index; end
|
688
|
-
def
|
718
|
+
def recalculate; end
|
689
719
|
end
|
690
720
|
|
691
721
|
```
|
692
722
|
## Ducalis::RubocopDisable
|
693
723
|
|
724
|
+
Please, do not suppress RuboCop metrics, may be you can introduce some
|
725
|
+
refactoring or another concept.
|
694
726
|
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
![](https://placehold.it/15/f03c15/000000?text=+) raises on RuboCop disable comments
|
727
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises on RuboCop disable comments
|
699
728
|
```ruby
|
700
729
|
|
701
730
|
# rubocop:disable Metrics/ParameterLists
|
702
|
-
def
|
731
|
+
def calculate(five, args, at, one, list); end
|
703
732
|
|
704
733
|
```
|
705
734
|
|
706
|
-
![](https://placehold.it/
|
735
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores comment without RuboCop disabling
|
707
736
|
```ruby
|
708
737
|
|
709
738
|
# some meaningful comment
|
710
|
-
def
|
739
|
+
def calculate(five, args, at, one, list); end
|
711
740
|
|
712
741
|
```
|
713
742
|
## Ducalis::StringsInActiverecords
|
714
743
|
|
715
744
|
Please, do not use strings as arguments for %<method_name>s argument.
|
716
|
-
It's hard to test, grep sources, code highlighting and so on.
|
717
|
-
Consider using of symbols or lambdas for complex expressions.
|
745
|
+
It's hard to test, grep sources, code highlighting and so on.
|
746
|
+
Consider using of symbols or lambdas for complex expressions.
|
718
747
|
|
719
|
-
![](https://placehold.it/
|
748
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for string if argument
|
720
749
|
```ruby
|
721
750
|
|
722
751
|
before_save :set_full_name,
|
@@ -724,129 +753,152 @@ before_save :set_full_name,
|
|
724
753
|
|
725
754
|
```
|
726
755
|
|
727
|
-
![](https://placehold.it/
|
756
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores lambda if argument
|
728
757
|
```ruby
|
729
758
|
validates :file, if: -> { remote_url.blank? }
|
730
759
|
```
|
731
760
|
## Ducalis::UncommentedGem
|
732
761
|
|
733
|
-
Please, add comment why are you including non-realized gem version for
|
734
|
-
It will increase
|
762
|
+
Please, add comment why are you including non-realized gem version for
|
763
|
+
%<gem>s. It will increase
|
764
|
+
[bus-factor](<https://en.wikipedia.org/wiki/Bus_factor>).
|
735
765
|
|
736
|
-
![](https://placehold.it/
|
766
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for gem from github without comment
|
737
767
|
```ruby
|
738
768
|
|
739
|
-
gem '
|
740
|
-
gem '
|
741
|
-
gem '
|
769
|
+
gem 'pry', '~> 0.10', '>= 0.10.0'
|
770
|
+
gem 'rake', '~> 12.1'
|
771
|
+
gem 'rspec', git: 'https://github.com/rspec/rspec'
|
742
772
|
|
743
773
|
```
|
744
774
|
|
745
|
-
![](https://placehold.it/
|
775
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores for gem from github with comment
|
746
776
|
```ruby
|
747
777
|
|
748
|
-
gem '
|
749
|
-
gem '
|
750
|
-
gem '
|
778
|
+
gem 'pry', '~> 0.10', '>= 0.10.0'
|
779
|
+
gem 'rake', '~> 12.1'
|
780
|
+
gem 'rspec', github: 'rspec/rspec' # new non released API
|
751
781
|
|
752
782
|
```
|
753
783
|
## Ducalis::UselessOnly
|
754
784
|
|
755
|
-
Seems like there is no any reason to keep before filter only for one
|
785
|
+
Seems like there is no any reason to keep before filter only for one
|
786
|
+
action. Maybe it will be better to inline it?
|
756
787
|
|
757
|
-
```ruby
|
758
|
-
before_filter :do_something, only: %i[index]
|
759
|
-
def index; end
|
788
|
+
```ruby
|
789
|
+
before_filter :do_something, only: %i[index]
|
790
|
+
def index; end
|
760
791
|
|
761
|
-
# to
|
792
|
+
# to
|
762
793
|
|
763
|
-
def index
|
764
|
-
|
765
|
-
end
|
766
|
-
```
|
794
|
+
def index
|
795
|
+
do_something
|
796
|
+
end
|
797
|
+
```
|
767
798
|
|
768
|
-
![](https://placehold.it/
|
799
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for `before_filters` with only one method as array
|
769
800
|
```ruby
|
770
801
|
|
771
|
-
class
|
772
|
-
before_filter :
|
802
|
+
class ProductsController < ApplicationController
|
803
|
+
before_filter :update_cost, only: [:index]
|
804
|
+
|
773
805
|
def index; end
|
806
|
+
|
774
807
|
private
|
775
|
-
|
808
|
+
|
809
|
+
def update_cost; end
|
776
810
|
end
|
777
811
|
|
778
812
|
```
|
779
813
|
|
780
|
-
![](https://placehold.it/
|
814
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for `before_filters` with only one method as keyword array
|
781
815
|
```ruby
|
782
816
|
|
783
|
-
class
|
784
|
-
before_filter :
|
817
|
+
class ProductsController < ApplicationController
|
818
|
+
before_filter :update_cost, only: %i[index]
|
819
|
+
|
785
820
|
def index; end
|
821
|
+
|
786
822
|
private
|
787
|
-
|
823
|
+
|
824
|
+
def update_cost; end
|
788
825
|
end
|
789
826
|
|
790
827
|
```
|
791
828
|
|
792
|
-
![](https://placehold.it/
|
829
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for `before_filters` with many actions and only one method
|
793
830
|
```ruby
|
794
831
|
|
795
|
-
class
|
796
|
-
before_filter :
|
832
|
+
class ProductsController < ApplicationController
|
833
|
+
before_filter :update_cost, :load_me, only: %i[index]
|
834
|
+
|
797
835
|
def index; end
|
836
|
+
|
798
837
|
private
|
799
|
-
|
838
|
+
|
839
|
+
def update_cost; end
|
800
840
|
def load_me; end
|
801
841
|
end
|
802
842
|
|
803
843
|
```
|
804
844
|
|
805
|
-
![](https://placehold.it/
|
845
|
+
![](https://placehold.it/10/f03c15/000000?text=+) raises for `before_filters` with only one method as argument
|
806
846
|
```ruby
|
807
847
|
|
808
|
-
class
|
809
|
-
before_filter :
|
848
|
+
class ProductsController < ApplicationController
|
849
|
+
before_filter :update_cost, only: :index
|
850
|
+
|
810
851
|
def index; end
|
852
|
+
|
811
853
|
private
|
812
|
-
|
854
|
+
|
855
|
+
def update_cost; end
|
813
856
|
end
|
814
857
|
|
815
858
|
```
|
816
859
|
|
817
|
-
![](https://placehold.it/
|
860
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores `before_filters` without arguments
|
818
861
|
```ruby
|
819
862
|
|
820
|
-
class
|
821
|
-
before_filter :
|
863
|
+
class ProductsController < ApplicationController
|
864
|
+
before_filter :update_cost
|
865
|
+
|
822
866
|
def index; end
|
867
|
+
|
823
868
|
private
|
824
|
-
|
869
|
+
|
870
|
+
def update_cost; end
|
825
871
|
end
|
826
872
|
|
827
873
|
```
|
828
874
|
|
829
|
-
![](https://placehold.it/
|
875
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores `before_filters` with `only` and many arguments
|
830
876
|
```ruby
|
831
877
|
|
832
|
-
class
|
833
|
-
before_filter :
|
878
|
+
class ProductsController < ApplicationController
|
879
|
+
before_filter :update_cost, only: %i[index show]
|
880
|
+
|
834
881
|
def index; end
|
835
882
|
def show; end
|
883
|
+
|
836
884
|
private
|
837
|
-
|
885
|
+
|
886
|
+
def update_cost; end
|
838
887
|
end
|
839
888
|
|
840
889
|
```
|
841
890
|
|
842
|
-
![](https://placehold.it/
|
891
|
+
![](https://placehold.it/10/2cbe4e/000000?text=+) ignores `before_filters` with `except` and one argument
|
843
892
|
```ruby
|
844
893
|
|
845
|
-
class
|
846
|
-
before_filter :
|
894
|
+
class ProductsController < ApplicationController
|
895
|
+
before_filter :update_cost, except: %i[index]
|
896
|
+
|
847
897
|
def index; end
|
898
|
+
|
848
899
|
private
|
849
|
-
|
900
|
+
|
901
|
+
def update_cost; end
|
850
902
|
end
|
851
903
|
|
852
904
|
```
|