rubocop-asjer 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6401e9b5d10c63a9c3ff7f3292aac36e8368a54fdd4df3062efda177ee331c11
4
- data.tar.gz: a7e90b0a705e59b161b575fdedb087d82b54dd8af3cfec7509bc54553012c5f5
3
+ metadata.gz: 447e874612f95f1d94bce6efa0da2fcfe9e06c1b72f624fb707ddc147c5280c3
4
+ data.tar.gz: a815ca7e0101b2e2d1bac4bfed12718ef10e95da304dfafa83c2bc74ef10b094
5
5
  SHA512:
6
- metadata.gz: a0f223e4e32b83736f21750b9ebb06ab49eacd9e2ccb45d37f047b231d763cb4f4dd1effa7bb87e0376f04db89287b48a7727c544b84b96585b657a02d2fa092
7
- data.tar.gz: '0810af3f8f3b56e7ae3b4ee4295805a9a01ee0cb34911da8d6197db60ff1d0f8ad3a37d596d8411ced98e2eae0fb13c60f904903bebea26b2302b52cdc66d3de'
6
+ metadata.gz: 59c42f2eb2390c5356d9afbe628a48652707c9ff3527306e2e83c29e48e9fbd04f1cfefd01f0d6b7d6da06198777d4a31721f2cce51319652ba24325d93a71a7
7
+ data.tar.gz: f0486413521d14aded52af6e496addd3f015c44ca832e393bb445b127c065f82e0aa0d3e906dd72bcda71439f5a451fbf68729afb89dec09182e7de06639d81a
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.4.1"
2
+ ".": "0.4.2"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.2](https://github.com/asjer/rubocop-asjer/compare/v0.4.1...v0.4.2) (2026-01-28)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * add missing rails classes to `RailsClassOrder` cop configuration ([0ddc16a](https://github.com/asjer/rubocop-asjer/commit/0ddc16a165530b0aa5c4e0d37195324779fca9a8))
9
+
3
10
  ## [0.4.1](https://github.com/asjer/rubocop-asjer/compare/v0.4.0...v0.4.1) (2026-01-28)
4
11
 
5
12
 
data/config/default.yml CHANGED
@@ -9,33 +9,71 @@ Asjer/RailsClassOrder:
9
9
  VersionAdded: "0.4.0"
10
10
  Include:
11
11
  - 'app/models/**/*.rb'
12
+ Scopes:
13
+ - default_scope
14
+ - scope
15
+ Attributes:
16
+ - attr_accessor
17
+ - attr_reader
18
+ - attr_writer
19
+ - attr_readonly
20
+ - attribute
21
+ - serialize
22
+ - store
23
+ - store_accessor
24
+ Enums:
25
+ - enum
12
26
  Associations:
13
27
  - belongs_to
14
- - has_many
15
28
  - has_one
29
+ - has_many
16
30
  - has_and_belongs_to_many
31
+ - has_one_attached
32
+ - has_many_attached
33
+ Validations:
34
+ - validates
35
+ - validates_acceptance_of
36
+ - validates_associated
37
+ - validates_comparison_of
38
+ - validates_confirmation_of
39
+ - validates_each
40
+ - validates_exclusion_of
41
+ - validates_format_of
42
+ - validates_inclusion_of
43
+ - validates_length_of
44
+ - validates_size_of
45
+ - validates_numericality_of
46
+ - validates_presence_of
47
+ - validates_uniqueness_of
48
+ - validates_with
49
+ - validate
17
50
  Callbacks:
18
51
  - after_initialize
19
52
  - after_find
20
53
  - after_touch
21
54
  - before_validation
22
- - validates
23
- - validate
24
55
  - after_validation
25
56
  - before_save
26
57
  - around_save
27
58
  - before_create
28
59
  - around_create
60
+ - after_create
29
61
  - before_update
30
62
  - around_update
63
+ - after_update
64
+ - after_save
31
65
  - before_destroy
32
66
  - around_destroy
33
67
  - after_destroy
34
- - after_update
35
- - after_create
36
- - after_save
37
68
  - after_commit
38
69
  - after_rollback
39
70
  Others:
40
- - attr_readonly
41
- - serialize
71
+ - encrypts
72
+ - normalizes
73
+ - delegate
74
+ - delegate_missing_to
75
+ - accepts_nested_attributes_for
76
+ - has_secure_password
77
+ - has_secure_token
78
+ - generates_token_for
79
+ - composed_of
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Asjer
5
- VERSION = '0.4.1'
5
+ VERSION = '0.4.2'
6
6
  end
7
7
  end
@@ -5,11 +5,12 @@ module RuboCop
5
5
  module Asjer
6
6
  # Enforces consistent ordering of declarative methods in Rails models.
7
7
  #
8
- # Methods are grouped into three categories: associations, callbacks,
9
- # and others. Within each category, methods are sorted by their position
10
- # in the configured list. Groups are separated by blank lines.
8
+ # Methods are grouped into seven categories following Rails Style Guide:
9
+ # scopes, attributes, enums, associations, validations, callbacks, and others.
10
+ # Within each category, methods are sorted by their position in the configured list.
11
+ # Groups are separated by blank lines.
11
12
  #
12
- # The order is: associations, then callbacks, then others.
13
+ # The order is: scopes, attributes, enums, associations, validations, callbacks, then others.
13
14
  #
14
15
  # @example
15
16
  # # bad
@@ -18,7 +19,9 @@ module RuboCop
18
19
  # validate :validate_name
19
20
  # after_create :after_create_1
20
21
  # has_many :messages
22
+ # scope :active, -> { where(active: true) }
21
23
  # attr_readonly :email
24
+ # enum :status, [:pending, :active]
22
25
  # after_create :after_create_2
23
26
  # belongs_to :role
24
27
  # before_create :set_name
@@ -26,34 +29,64 @@ module RuboCop
26
29
  #
27
30
  # # good
28
31
  # class User < ApplicationRecord
32
+ # scope :active, -> { where(active: true) }
33
+ #
34
+ # attr_readonly :email
35
+ #
36
+ # enum :status, [:pending, :active]
37
+ #
29
38
  # belongs_to :plan
30
39
  # belongs_to :role
31
40
  # has_many :messages
32
41
  #
33
42
  # validate :validate_name
43
+ #
34
44
  # before_create :set_name
35
45
  # after_create :after_create_1
36
46
  # after_create :after_create_2
37
- #
38
- # attr_readonly :email
39
47
  # end
40
48
  #
41
49
  # Default method lists for RailsClassOrder cop
42
50
  module RailsClassOrderDefaults
51
+ SCOPES = %w[default_scope scope].freeze
52
+
53
+ ATTRIBUTES = %w[
54
+ attr_accessor attr_reader attr_writer attr_readonly
55
+ attribute serialize store store_accessor
56
+ ].freeze
57
+
58
+ ENUMS = %w[enum].freeze
59
+
43
60
  ASSOCIATIONS = %w[
44
- belongs_to has_many has_one has_and_belongs_to_many
61
+ belongs_to has_one has_many has_and_belongs_to_many
62
+ has_one_attached has_many_attached
63
+ ].freeze
64
+
65
+ VALIDATIONS = %w[
66
+ validates validates_acceptance_of validates_associated
67
+ validates_comparison_of validates_confirmation_of validates_each
68
+ validates_exclusion_of validates_format_of validates_inclusion_of
69
+ validates_length_of validates_size_of validates_numericality_of
70
+ validates_presence_of validates_uniqueness_of validates_with
71
+ validate
45
72
  ].freeze
46
73
 
47
74
  CALLBACKS = %w[
48
75
  after_initialize after_find after_touch
49
- before_validation validates validate after_validation
50
- before_save around_save before_create around_create
51
- before_update around_update before_destroy around_destroy
52
- after_destroy after_update after_create after_save
76
+ before_validation after_validation
77
+ before_save around_save
78
+ before_create around_create after_create
79
+ before_update around_update after_update
80
+ after_save
81
+ before_destroy around_destroy after_destroy
53
82
  after_commit after_rollback
54
83
  ].freeze
55
84
 
56
- OTHERS = %w[attr_readonly serialize].freeze
85
+ OTHERS = %w[
86
+ encrypts normalizes delegate delegate_missing_to
87
+ accepts_nested_attributes_for has_secure_password
88
+ has_secure_token generates_token_for composed_of
89
+ ].freeze
57
90
  end
58
91
 
59
92
  # Autocorrect helpers for RailsClassOrder cop
@@ -101,8 +134,11 @@ module RuboCop
101
134
  def build_sorted_source(sorted, original)
102
135
  indent = ' ' * original.first.loc.column
103
136
  grouped = sorted.group_by { |m| method_type(m) }
137
+ format_grouped_source(grouped, indent)
138
+ end
104
139
 
105
- %i[association callback other].filter_map do |type|
140
+ def format_grouped_source(grouped, indent)
141
+ self.class::TYPE_ORDER.keys.filter_map do |type|
106
142
  next unless grouped[type]&.any?
107
143
 
108
144
  grouped[type].map { |m| source_with_comments(m) }.join("\n#{indent}")
@@ -123,8 +159,28 @@ module RuboCop
123
159
  include RangeHelp
124
160
  include RailsClassOrderCorrector
125
161
 
126
- MSG = 'Declarative methods should be sorted by type: associations, callbacks, then others.'
127
- TYPE_ORDER = { association: 0, callback: 1, other: 2 }.freeze
162
+ MSG = 'Declarative methods should be sorted by type: scopes, attributes, enums, ' \
163
+ 'associations, validations, callbacks, then others.'
164
+
165
+ TYPE_ORDER = {
166
+ scope: 0,
167
+ attribute: 1,
168
+ enum: 2,
169
+ association: 3,
170
+ validation: 4,
171
+ callback: 5,
172
+ other: 6
173
+ }.freeze
174
+
175
+ CATEGORY_CONFIG = {
176
+ scope: { key: 'Scopes', const: :SCOPES },
177
+ attribute: { key: 'Attributes', const: :ATTRIBUTES },
178
+ enum: { key: 'Enums', const: :ENUMS },
179
+ association: { key: 'Associations', const: :ASSOCIATIONS },
180
+ validation: { key: 'Validations', const: :VALIDATIONS },
181
+ callback: { key: 'Callbacks', const: :CALLBACKS },
182
+ other: { key: 'Others', const: :OTHERS }
183
+ }.freeze
128
184
 
129
185
  def on_class(node)
130
186
  _name, _superclass, body = *node
@@ -146,20 +202,17 @@ module RuboCop
146
202
  add_offense(first_misplaced) { |corrector| autocorrect(corrector, body, targets, sorted) }
147
203
  end
148
204
 
149
- def associations
150
- @associations ||= cop_config.fetch('Associations', RailsClassOrderDefaults::ASSOCIATIONS).map(&:to_sym)
151
- end
152
-
153
- def callbacks
154
- @callbacks ||= cop_config.fetch('Callbacks', RailsClassOrderDefaults::CALLBACKS).map(&:to_sym)
155
- end
156
-
157
- def others
158
- @others ||= cop_config.fetch('Others', RailsClassOrderDefaults::OTHERS).map(&:to_sym)
205
+ def category_methods(category)
206
+ cfg = CATEGORY_CONFIG[category]
207
+ instance_variable_get(:"@#{category}") ||
208
+ instance_variable_set(
209
+ :"@#{category}",
210
+ cop_config.fetch(cfg[:key], RailsClassOrderDefaults.const_get(cfg[:const])).map(&:to_sym)
211
+ )
159
212
  end
160
213
 
161
214
  def all_target_methods
162
- @all_target_methods ||= associations + callbacks + others
215
+ @all_target_methods ||= TYPE_ORDER.keys.flat_map { |cat| category_methods(cat) }
163
216
  end
164
217
 
165
218
  def target_methods(body)
@@ -167,14 +220,16 @@ module RuboCop
167
220
  end
168
221
 
169
222
  def sort_methods(methods)
170
- methods.each_with_index.sort_by { |m, i| [method_type_order(m), method_position_in_type(m), i] }.map(&:first)
223
+ methods.each_with_index.sort_by do |method, index|
224
+ [method_type_order(method), method_position_in_type(method), index]
225
+ end.map(&:first)
171
226
  end
172
227
 
173
228
  def method_type(method)
174
229
  name = method.method_name
175
- return :association if associations.include?(name)
176
- return :callback if callbacks.include?(name)
177
-
230
+ TYPE_ORDER.each_key do |category|
231
+ return category if category_methods(category).include?(name)
232
+ end
178
233
  :other
179
234
  end
180
235
 
@@ -183,11 +238,8 @@ module RuboCop
183
238
  end
184
239
 
185
240
  def method_position_in_type(method)
186
- method_list_for_type(method_type(method)).index(method.method_name) || 999
187
- end
188
-
189
- def method_list_for_type(type)
190
- { association: associations, callback: callbacks, other: others }[type]
241
+ list = category_methods(method_type(method))
242
+ list.index(method.method_name) || list.size
191
243
  end
192
244
  end
193
245
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-asjer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Asjer Querido