Skip to content

Commit 0e5a962

Browse files
committed
[Fix #664] Fix a false positive for Rails/MigrationClassName cop
Fixes #664. This PR fixes a false positive for `Rails/MigrationClassName` when `ActiveSupport::Inflector` is applied to the class name and the case is different. Occasionally user want to treat a word like `Oauth` as` OAuth`. This PR is case insensitive for comparisons between migration class name and filename. It's may not a big deal because it's based on filename.
1 parent 8373c5a commit 0e5a962

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#664](https://github.com/rubocop/rubocop-rails/issues/664): Fix a false positive for `Rails/MigrationClassName` when `ActiveSupport::Inflector` is applied to the class name and the case is different. ([@koic][])

lib/rubocop/cop/rails/migration_class_name.rb

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,30 @@ class MigrationClassName < Base
2222
extend AutoCorrector
2323
include MigrationsHelper
2424

25-
MSG = 'Replace with `%<corrected_class_name>s` that matches the file name.'
25+
MSG = 'Replace with `%<camelized_basename>s` that matches the file name.'
2626

2727
def on_class(node)
2828
return if in_migration?(node)
2929

30-
snake_class_name = to_snakecase(node.identifier.source)
30+
basename = basename_without_timestamp_and_suffix(processed_source.file_path)
3131

32-
basename = basename_without_timestamp_and_suffix
33-
return if snake_class_name == basename
32+
class_identifier = node.identifier
33+
camelized_basename = camelize(basename)
34+
return if class_identifier.source.casecmp(camelized_basename).zero?
3435

35-
corrected_class_name = to_camelcase(basename)
36-
message = format(MSG, corrected_class_name: corrected_class_name)
36+
message = format(MSG, camelized_basename: camelized_basename)
3737

38-
add_offense(node.identifier, message: message) do |corrector|
39-
corrector.replace(node.identifier, corrected_class_name)
38+
add_offense(class_identifier, message: message) do |corrector|
39+
corrector.replace(class_identifier, camelized_basename)
4040
end
4141
end
4242

4343
private
4444

45-
def basename_without_timestamp_and_suffix
46-
filepath = processed_source.file_path
45+
def basename_without_timestamp_and_suffix(filepath)
4746
basename = File.basename(filepath, '.rb')
4847
basename = remove_gem_suffix(basename)
48+
4949
basename.sub(/\A\d+_/, '')
5050
end
5151

@@ -54,17 +54,9 @@ def remove_gem_suffix(file_name)
5454
file_name.sub(/\..+\z/, '')
5555
end
5656

57-
def to_camelcase(word)
57+
def camelize(word)
5858
word.split('_').map(&:capitalize).join
5959
end
60-
61-
def to_snakecase(word)
62-
word
63-
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
64-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
65-
.tr('-', '_')
66-
.downcase
67-
end
6860
end
6961
end
7062
end

spec/rubocop/cop/rails/migration_class_name_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,23 @@ class AddBlobs < ActiveRecord::Migration[7.0]
4848
RUBY
4949
end
5050
end
51+
52+
#
53+
# When `OAuth` is applied instead of `Oauth` for `oauth`.
54+
#
55+
# # config/initializers/inflections.rb
56+
# ActiveSupport::Inflector.inflections(:en) do |inflect|
57+
# inflect.acronym 'OAuth'
58+
# end
59+
#
60+
context 'when `ActiveSupport::Inflector` is applied to the class name and the case is different' do
61+
let(:filename) { 'db/migrate/20210623095243_remove_unused_oauth_scope_grants.rb' }
62+
63+
it 'does not register an offense' do
64+
expect_no_offenses(<<~RUBY, filename)
65+
class RemoveUnusedOAuthScopeGrants < ActiveRecord::Migration[7.0]
66+
end
67+
RUBY
68+
end
69+
end
5170
end

0 commit comments

Comments
 (0)