From 482779255b43a01646a58569935fc2273b2f55f2 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:32:52 +0200 Subject: [PATCH 01/23] Fix wrong autocorrect for `Rails/FilePath` when passing an array to `File.join` `File.join` actually accepts nested arrays and will unflatten them as necessary. Don't bother implementing autocorrect for these cases, seems complicated and not worth the effort. The current correction for these testcases look like this: ```rb Rails.root.join().to_s ``` --- ...x_wrong_autocorrect_for_rails_file_path.md | 1 + lib/rubocop/cop/rails/file_path.rb | 2 +- spec/rubocop/cop/rails/file_path_spec.rb | 20 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_wrong_autocorrect_for_rails_file_path.md diff --git a/changelog/fix_wrong_autocorrect_for_rails_file_path.md b/changelog/fix_wrong_autocorrect_for_rails_file_path.md new file mode 100644 index 0000000000..10b2da3ae5 --- /dev/null +++ b/changelog/fix_wrong_autocorrect_for_rails_file_path.md @@ -0,0 +1 @@ +* [#1326](https://github.com/rubocop/rubocop-rails/pull/1326): Fix wrong autocorrect for `Rails/FilePath` when passing an array to `File.join`. ([@earlopain][]) diff --git a/lib/rubocop/cop/rails/file_path.rb b/lib/rubocop/cop/rails/file_path.rb index f98f37076f..02459031a9 100644 --- a/lib/rubocop/cop/rails/file_path.rb +++ b/lib/rubocop/cop/rails/file_path.rb @@ -97,7 +97,7 @@ def check_for_file_join_with_rails_root(node) return unless node.arguments.any? { |e| rails_root_nodes?(e) } register_offense(node, require_to_s: true) do |corrector| - autocorrect_file_join(corrector, node) + autocorrect_file_join(corrector, node) unless node.first_argument.array_type? end end diff --git a/spec/rubocop/cop/rails/file_path_spec.rb b/spec/rubocop/cop/rails/file_path_spec.rb index 1993e66ba4..3bec9ded2c 100644 --- a/spec/rubocop/cop/rails/file_path_spec.rb +++ b/spec/rubocop/cop/rails/file_path_spec.rb @@ -114,6 +114,26 @@ end end + context 'when using File.join with an array' do + it 'registers an offense' do + expect_offense(<<~RUBY) + File.join([Rails.root, 'foo']) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`. + RUBY + + expect_no_corrections + end + + it 'registers an offense for nested arrays' do + expect_offense(<<~RUBY) + File.join([Rails.root, 'foo', ['bar']]) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`. + RUBY + + expect_no_corrections + end + end + context 'when using Rails.root.join with slash separated path string' do it 'does not register an offense' do expect_no_offenses("Rails.root.join('app/models/goober')") From 8fa685685cc4983dd7a94332608cd79b54272f07 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 24 Aug 2024 17:18:40 +0900 Subject: [PATCH 02/23] Switch back docs version to master --- docs/antora.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/antora.yml b/docs/antora.yml index 0e3477f379..9e0ff48acb 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop-rails title: RuboCop Rails # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: '2.26' +version: ~ nav: - modules/ROOT/nav.adoc From 0909f0ebe5df723b26f057243ade4e046957a512 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Sat, 24 Aug 2024 12:06:10 +0200 Subject: [PATCH 03/23] Remove RuboCop < 1.52 compatibility code The minimum required version right now is >= 1.52 --- lib/rubocop/cop/rails/action_order.rb | 6 +--- .../rails/active_record_callbacks_order.rb | 6 +--- .../redundant_active_record_all_method.rb | 29 ------------------- 3 files changed, 2 insertions(+), 39 deletions(-) diff --git a/lib/rubocop/cop/rails/action_order.rb b/lib/rubocop/cop/rails/action_order.rb index a2bcd3b462..954c1ae2fd 100644 --- a/lib/rubocop/cop/rails/action_order.rb +++ b/lib/rubocop/cop/rails/action_order.rb @@ -92,11 +92,7 @@ def add_range(range1, range2) end def range_with_comments(node) - # rubocop:todo InternalAffairs/LocationExpression - # Using `RuboCop::Ext::Comment#source_range` requires RuboCop > 1.46, - # which introduces https://github.com/rubocop/rubocop/pull/11630. - ranges = [node, *processed_source.ast_with_comments[node]].map { |comment| comment.loc.expression } - # rubocop:enable InternalAffairs/LocationExpression + ranges = [node, *processed_source.ast_with_comments[node]].map(&:source_range) ranges.reduce do |result, range| add_range(result, range) end diff --git a/lib/rubocop/cop/rails/active_record_callbacks_order.rb b/lib/rubocop/cop/rails/active_record_callbacks_order.rb index 8742e76338..cb544234f6 100644 --- a/lib/rubocop/cop/rails/active_record_callbacks_order.rb +++ b/lib/rubocop/cop/rails/active_record_callbacks_order.rb @@ -123,11 +123,7 @@ def begin_pos_with_comment(node) end def inline_comment?(comment) - # rubocop:todo InternalAffairs/LocationExpression - # Using `RuboCop::Ext::Comment#source_range` requires RuboCop > 1.46, - # which introduces https://github.com/rubocop/rubocop/pull/11630. - !comment_line?(comment.loc.expression.source_line) - # rubocop:enable InternalAffairs/LocationExpression + !comment_line?(comment.source_range.source_line) end def start_line_position(node) diff --git a/lib/rubocop/cop/rails/redundant_active_record_all_method.rb b/lib/rubocop/cop/rails/redundant_active_record_all_method.rb index ee5fa6afd6..252e890875 100644 --- a/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +++ b/lib/rubocop/cop/rails/redundant_active_record_all_method.rb @@ -3,35 +3,6 @@ module RuboCop module Cop module Rails - # TODO: In the future, please support only RuboCop 1.52+ and use `RuboCop::Cop::AllowedReceivers`: - # https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cop/mixin/allowed_receivers.rb - # At that time, this duplicated module implementation can be removed. - module AllowedReceivers - def allowed_receiver?(receiver) - receiver_name = receiver_name(receiver) - - allowed_receivers.include?(receiver_name) - end - - def receiver_name(receiver) - return receiver_name(receiver.receiver) if receiver.receiver && !receiver.receiver.const_type? - - if receiver.send_type? - if receiver.receiver - "#{receiver_name(receiver.receiver)}.#{receiver.method_name}" - else - receiver.method_name.to_s - end - else - receiver.source - end - end - - def allowed_receivers - cop_config.fetch('AllowedReceivers', []) - end - end - # Detect redundant `all` used as a receiver for Active Record query methods. # # For the methods `delete_all` and `destroy_all`, this cop will only check cases where the receiver is a model. From d83f48a061972977fd277066f188a5d2f58953e8 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Mon, 26 Aug 2024 10:50:22 +0200 Subject: [PATCH 04/23] Enable `InternalAffairs/UndefinedConfig` This works fine right now. I did a bit of spelunking for `NilOrEmpty` in `Rails/Present` and I believe it is a copy-paste error. Added together with `Rails/Blank` in https://github.com/rubocop/rubocop/pull/4133/ which does contain this config value. There are no tests or docs for this config value. --- .rubocop.yml | 4 ---- lib/rubocop/cop/rails/present.rb | 2 -- lib/rubocop/cop/rails/skips_model_validations.rb | 6 ++++-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 43ee5e077b..dc83f549fc 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -19,10 +19,6 @@ AllCops: InternalAffairs/NodeMatcherDirective: Enabled: false -# FIXME: Workaround for a false positive caused by this cop when using `bundle exec rake`. -InternalAffairs/UndefinedConfig: - Enabled: false - Naming/InclusiveLanguage: Enabled: true CheckStrings: true diff --git a/lib/rubocop/cop/rails/present.rb b/lib/rubocop/cop/rails/present.rb index 1d789cf7bd..3d77f33d6f 100644 --- a/lib/rubocop/cop/rails/present.rb +++ b/lib/rubocop/cop/rails/present.rb @@ -98,8 +98,6 @@ def on_and(node) end def on_or(node) - return unless cop_config['NilOrEmpty'] - exists_and_not_empty?(node) do |var1, var2| return unless var1 == var2 diff --git a/lib/rubocop/cop/rails/skips_model_validations.rb b/lib/rubocop/cop/rails/skips_model_validations.rb index 5a78926c92..58a6fe519d 100644 --- a/lib/rubocop/cop/rails/skips_model_validations.rb +++ b/lib/rubocop/cop/rails/skips_model_validations.rb @@ -100,7 +100,8 @@ def allowed_method?(node) end def forbidden_methods - obsolete_result = cop_config['Blacklist'] + # TODO: Remove when RuboCop Rails 3 releases. + obsolete_result = cop_config['Blacklist'] # rubocop:disable InternalAffairs/UndefinedConfig if obsolete_result warn '`Blacklist` has been renamed to `ForbiddenMethods`.' unless @displayed_forbidden_warning @displayed_forbidden_warning = true @@ -111,7 +112,8 @@ def forbidden_methods end def allowed_methods - obsolete_result = cop_config['Whitelist'] + # TODO: Remove when RuboCop Rails 3 releases. + obsolete_result = cop_config['Whitelist'] # rubocop:disable InternalAffairs/UndefinedConfig if obsolete_result warn '`Whitelist` has been renamed to `AllowedMethods`.' unless @displayed_allowed_warning @displayed_allowed_warning = true From 5c975e5f7480ef5134410b2364aca290f4870a74 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Mon, 26 Aug 2024 13:45:43 +0200 Subject: [PATCH 05/23] [Fix #1340] Fix a false positive for `Rails/WhereEquals` when qualifying the database name And `Rails/WhereNot`/``Rails/WhereRange` as well. I'd like to extract some of this logic to a module sometime since it is looking rather similar. The original issue mentions Redshift, and I know that MSSQL allows cross-database queries as well --- changelog/fix_false_positive_database_qualified.md | 1 + lib/rubocop/cop/rails/where_equals.rb | 7 ++++++- lib/rubocop/cop/rails/where_not.rb | 7 ++++++- lib/rubocop/cop/rails/where_range.rb | 7 ++++++- spec/rubocop/cop/rails/where_equals_spec.rb | 6 ++++++ spec/rubocop/cop/rails/where_not_spec.rb | 6 ++++++ spec/rubocop/cop/rails/where_range_spec.rb | 6 ++++++ 7 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_false_positive_database_qualified.md diff --git a/changelog/fix_false_positive_database_qualified.md b/changelog/fix_false_positive_database_qualified.md new file mode 100644 index 0000000000..50e815b818 --- /dev/null +++ b/changelog/fix_false_positive_database_qualified.md @@ -0,0 +1 @@ +* [#1340](https://github.com/rubocop/rubocop-rails/issues/1340): Fix a false positive for `Rails/WhereEquals`, `Rails/WhereNot`, and `Rails/WhereRange` when qualifying the database name. ([@earlopain][]) diff --git a/lib/rubocop/cop/rails/where_equals.rb b/lib/rubocop/cop/rails/where_equals.rb index b1d56b7c24..b538bedd8d 100644 --- a/lib/rubocop/cop/rails/where_equals.rb +++ b/lib/rubocop/cop/rails/where_equals.rb @@ -74,6 +74,7 @@ def offense_range(node) range_between(node.loc.selector.begin_pos, node.source_range.end_pos) end + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def extract_column_and_value(template_node, value_node) value = case template_node.value @@ -90,8 +91,12 @@ def extract_column_and_value(template_node, value_node) return end - [Regexp.last_match(1), value] + column_qualifier = Regexp.last_match(1) + return if column_qualifier.count('.') > 1 + + [column_qualifier, value] end + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def build_good_method(method_name, column, value) if column.include?('.') diff --git a/lib/rubocop/cop/rails/where_not.rb b/lib/rubocop/cop/rails/where_not.rb index 96762f5e47..2b6300165e 100644 --- a/lib/rubocop/cop/rails/where_not.rb +++ b/lib/rubocop/cop/rails/where_not.rb @@ -68,6 +68,7 @@ def offense_range(node) range_between(node.loc.selector.begin_pos, node.source_range.end_pos) end + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def extract_column_and_value(template_node, value_node) value = case template_node.value @@ -84,8 +85,12 @@ def extract_column_and_value(template_node, value_node) return end - [Regexp.last_match(1), value] + column_qualifier = Regexp.last_match(1) + return if column_qualifier.count('.') > 1 + + [column_qualifier, value] end + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def build_good_method(dot, column, value) dot ||= '.' diff --git a/lib/rubocop/cop/rails/where_range.rb b/lib/rubocop/cop/rails/where_range.rb index 4797a50e81..1c8fd4a0fb 100644 --- a/lib/rubocop/cop/rails/where_range.rb +++ b/lib/rubocop/cop/rails/where_range.rb @@ -140,6 +140,8 @@ def extract_column_and_value(template_node, values_node) rhs = pair2.value end end + else + return end if lhs @@ -150,7 +152,10 @@ def extract_column_and_value(template_node, values_node) rhs_source = parentheses_needed?(rhs) ? "(#{rhs.source})" : rhs.source end - [Regexp.last_match(1), "#{lhs_source}#{operator}#{rhs_source}"] if operator + column_qualifier = Regexp.last_match(1) + return if column_qualifier.count('.') > 1 + + [column_qualifier, "#{lhs_source}#{operator}#{rhs_source}"] if operator end # rubocop:enable Metrics diff --git a/spec/rubocop/cop/rails/where_equals_spec.rb b/spec/rubocop/cop/rails/where_equals_spec.rb index 1af170ebff..5c564a72e7 100644 --- a/spec/rubocop/cop/rails/where_equals_spec.rb +++ b/spec/rubocop/cop/rails/where_equals_spec.rb @@ -217,4 +217,10 @@ users.not('name = ?', 'Gabe') RUBY end + + it 'does not register an offense when qualifying the database' do + expect_no_offenses(<<~RUBY) + User.where('database.users.name = ?', 'Gabe') + RUBY + end end diff --git a/spec/rubocop/cop/rails/where_not_spec.rb b/spec/rubocop/cop/rails/where_not_spec.rb index 84d8aeded0..36e1ecca54 100644 --- a/spec/rubocop/cop/rails/where_not_spec.rb +++ b/spec/rubocop/cop/rails/where_not_spec.rb @@ -275,4 +275,10 @@ User.where('name <> ? AND age <> ?', 'john', 19) RUBY end + + it 'does not register an offense when qualifying the database' do + expect_no_offenses(<<~RUBY) + User.where('database.users.name != ?', 'Gabe') + RUBY + end end diff --git a/spec/rubocop/cop/rails/where_range_spec.rb b/spec/rubocop/cop/rails/where_range_spec.rb index 6a5a7b3353..4102fee308 100644 --- a/spec/rubocop/cop/rails/where_range_spec.rb +++ b/spec/rubocop/cop/rails/where_range_spec.rb @@ -221,6 +221,12 @@ Model.where(column: ...value) RUBY end + + it 'does not register an offense when qualifying the database' do + expect_no_offenses(<<~RUBY) + Model.where('database.table.column >= ?', value) + RUBY + end end end end From 0f36342a119659e3afc7385f4bc1e5791bb920ee Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:49:59 +0200 Subject: [PATCH 06/23] [Fix #1345] Improve offense message for `Rails/RootPathnameMethods` The current message is confusing/nonsensical for `Dir[]`. Let's display the correct code instead to show what needs to be done --- .../cop/rails/root_pathname_methods.rb | 18 ++++++++----- .../cop/rails/root_pathname_methods_spec.rb | 26 +++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/lib/rubocop/cop/rails/root_pathname_methods.rb b/lib/rubocop/cop/rails/root_pathname_methods.rb index 233b1744d0..5898d0b421 100644 --- a/lib/rubocop/cop/rails/root_pathname_methods.rb +++ b/lib/rubocop/cop/rails/root_pathname_methods.rb @@ -23,6 +23,8 @@ module Rails # File.binread(Rails.root.join('db', 'schema.rb')) # File.write(Rails.root.join('db', 'schema.rb'), content) # File.binwrite(Rails.root.join('db', 'schema.rb'), content) + # Dir.glob(Rails.root.join('db', 'schema.rb')) + # Dir[Rails.root.join('db', 'schema.rb')] # # # good # Rails.root.join('db', 'schema.rb').open @@ -31,12 +33,13 @@ module Rails # Rails.root.join('db', 'schema.rb').binread # Rails.root.join('db', 'schema.rb').write(content) # Rails.root.join('db', 'schema.rb').binwrite(content) + # Rails.root.glob("db/schema.rb") # class RootPathnameMethods < Base # rubocop:disable Metrics/ClassLength extend AutoCorrector include RangeHelp - MSG = '`%s` is a `Pathname` so you can just append `#%s`.' + MSG = '`%s` is a `Pathname`, so you can use `%s`.' DIR_GLOB_METHODS = %i[[] glob].to_set.freeze @@ -188,13 +191,14 @@ class RootPathnameMethods < Base # rubocop:disable Metrics/ClassLength def on_send(node) evidence(node) do |method, path, args, rails_root| - add_offense(node, message: format(MSG, method: method, rails_root: rails_root.source)) do |corrector| - replacement = if dir_glob?(node) - build_path_glob_replacement(path) - else - build_path_replacement(path, method, args) - end + replacement = if dir_glob?(node) + build_path_glob_replacement(path) + else + build_path_replacement(path, method, args) + end + message = format(MSG, rails_root: rails_root.source, replacement: replacement) + add_offense(node, message: message) do |corrector| corrector.replace(node, replacement) end end diff --git a/spec/rubocop/cop/rails/root_pathname_methods_spec.rb b/spec/rubocop/cop/rails/root_pathname_methods_spec.rb index 04b9508073..82f00ea5da 100644 --- a/spec/rubocop/cop/rails/root_pathname_methods_spec.rb +++ b/spec/rubocop/cop/rails/root_pathname_methods_spec.rb @@ -12,7 +12,7 @@ it "registers an offense when using `#{receiver}.#{method}(Rails.public_path)` (if arity exists)" do expect_offense(<<~RUBY, receiver: receiver, method: method) %{receiver}.%{method}(Rails.public_path) - ^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^ `Rails.public_path` is a `Pathname` so you can just append `#%{method}`. + ^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^ `Rails.public_path` is a `Pathname`, so you can use `Rails.public_path.%{method}`. RUBY expect_correction(<<~RUBY) @@ -23,7 +23,7 @@ it "registers an offense when using `::#{receiver}.#{method}(::Rails.root.join(...))` (if arity exists)" do expect_offense(<<~RUBY, receiver: receiver, method: method) ::%{receiver}.%{method}(::Rails.root.join('db', 'schema.rb')) - ^^^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `::Rails.root` is a `Pathname` so you can just append `#%{method}`. + ^^^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `::Rails.root` is a `Pathname`, so you can use `::Rails.root.join('db', 'schema.rb').%{method}`. RUBY expect_correction(<<~RUBY) @@ -34,7 +34,7 @@ it "registers an offense when using `::#{receiver}.#{method}(::Rails.root.join(...), ...)` (if arity exists)" do expect_offense(<<~RUBY, receiver: receiver, method: method) ::%{receiver}.%{method}(::Rails.root.join('db', 'schema.rb'), 20, 5) - ^^^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `::Rails.root` is a `Pathname` so you can just append `#%{method}`. + ^^^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `::Rails.root` is a `Pathname`, so you can use `::Rails.root.join('db', 'schema.rb').%{method}(20, 5)`. RUBY expect_correction(<<~RUBY) @@ -56,7 +56,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**/*.rb'))`" do expect_offense(<<~RUBY) Dir.glob(Rails.root.join('**/*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob('**/*.rb')`. RUBY expect_correction(<<~RUBY) @@ -67,7 +67,7 @@ it "registers an offense when using `::Dir.glob(Rails.root.join('**/*.rb'))`" do expect_offense(<<~RUBY) ::Dir.glob(Rails.root.join('**/*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob('**/*.rb')`. RUBY expect_correction(<<~RUBY) @@ -78,7 +78,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**/\#{path}/*.rb'))`" do expect_offense(<<~'RUBY') Dir.glob(Rails.root.join("**/#{path}/*.rb")) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob("**/#{path}/*.rb")`. RUBY expect_correction(<<~'RUBY') @@ -89,7 +89,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**', '*.rb'))`" do expect_offense(<<~RUBY) Dir.glob(Rails.root.join('**', '*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob('**/*.rb')`. RUBY expect_correction(<<~RUBY) @@ -105,7 +105,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**', '*.rb'))`" do expect_offense(<<~RUBY) Dir.glob(Rails.root.join('**', '*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob("**/*.rb")`. RUBY expect_correction(<<~RUBY) @@ -117,7 +117,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**', \"\#{path}\", '*.rb'))`" do expect_offense(<<~'RUBY') Dir.glob(Rails.root.join('**', "#{path}", '*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob("**/#{path}/*.rb")`. RUBY expect_correction(<<~'RUBY') @@ -128,7 +128,7 @@ it 'registers an offense when using `Rails.env` argument within `Dir.glob`' do expect_offense(<<~RUBY) Dir.glob(Rails.root.join("db", "seeds", Rails.env, "*.rb")).sort.each do |file| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob("db/seeds/\#{Rails.env}/*.rb")`. load file end RUBY @@ -145,7 +145,7 @@ it 'registers offense when using `Dir[Rails.root.join(...)]`' do expect_offense(<<~RUBY) Dir[Rails.root.join('spec/support/**/*.rb')] - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#[]`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob('spec/support/**/*.rb')`. RUBY expect_correction(<<~RUBY) @@ -192,7 +192,7 @@ it 'registers an offense when using `File.open(Rails.root.join(...), ...)` inside an iterator' do expect_offense(<<~RUBY) files.map { |file| File.open(Rails.root.join('db', file), 'wb') } - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#open`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join('db', file).open('wb')`. RUBY expect_correction(<<~RUBY) @@ -203,7 +203,7 @@ it 'registers an offense when using `File.open Rails.root.join ...` without parens' do expect_offense(<<~RUBY) file = File.open Rails.root.join 'docs', 'invoice.pdf' - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#open`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join('docs', 'invoice.pdf').open`. RUBY expect_correction(<<~RUBY) From 4c97338d95a6fe5ee454098cd4bd3bc174606e32 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:25:58 +0200 Subject: [PATCH 07/23] [Issue #1269] Revert #1344, add `Rails/ActionControllerFlashBeforeRender` tests from issue #1269 This reverts commit 0f703db581ffbf49830d0c1705c57129b6a7d4aa, reversing changes made to 0f63f00ecee27313e92eedad74a33b7c5ef21be1. This cop would need to do control flow analysis which it just doesn't do. RuboCop also has no mechanism for that. So just reverting this for now to fix the newly introduces false positives --- changelog/fix_revert_flash_before_render.md | 1 + .../action_controller_flash_before_render.rb | 10 +- ...ion_controller_flash_before_render_spec.rb | 246 +++++------------- 3 files changed, 74 insertions(+), 183 deletions(-) create mode 100644 changelog/fix_revert_flash_before_render.md diff --git a/changelog/fix_revert_flash_before_render.md b/changelog/fix_revert_flash_before_render.md new file mode 100644 index 0000000000..4a7cab0316 --- /dev/null +++ b/changelog/fix_revert_flash_before_render.md @@ -0,0 +1 @@ +* [#1269](https://github.com/rubocop/rubocop-rails/issues/1269): Fix false positives for `Rails/ActionControllerFlashBeforeRender` in combination with implicit returns. ([@earlopain][]) diff --git a/lib/rubocop/cop/rails/action_controller_flash_before_render.rb b/lib/rubocop/cop/rails/action_controller_flash_before_render.rb index bf4602cdab..806e92e455 100644 --- a/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +++ b/lib/rubocop/cop/rails/action_controller_flash_before_render.rb @@ -72,13 +72,13 @@ def followed_by_render?(flash_node) if (node = context.each_ancestor(:if, :rescue).first) return false if use_redirect_to?(context) - context = node.rescue_type? ? node.parent : node + context = node + elsif context.right_siblings.empty? + return true end + context = context.right_siblings - siblings = context.right_siblings - return true if siblings.empty? - - siblings.compact.any? do |render_candidate| + context.compact.any? do |render_candidate| render?(render_candidate) end end diff --git a/spec/rubocop/cop/rails/action_controller_flash_before_render_spec.rb b/spec/rubocop/cop/rails/action_controller_flash_before_render_spec.rb index 0c8f682e16..6ca55d122b 100644 --- a/spec/rubocop/cop/rails/action_controller_flash_before_render_spec.rb +++ b/spec/rubocop/cop/rails/action_controller_flash_before_render_spec.rb @@ -128,36 +128,9 @@ def create end end RUBY - - expect_offense(<<~RUBY) - class HomeController < #{parent_class} - def create - flash[:alert] = "msg" if condition - ^^^^^ Use `flash.now` before `render`. - end - end - RUBY - - expect_correction(<<~RUBY) - class HomeController < #{parent_class} - def create - flash.now[:alert] = "msg" if condition - end - end - RUBY end it 'does not register an offense when using `flash` before `redirect_to`' do - expect_no_offenses(<<~RUBY) - class HomeController < #{parent_class} - def create - flash[:alert] = "msg" if condition - - redirect_to :index - end - end - RUBY - expect_no_offenses(<<~RUBY) class HomeController < #{parent_class} def create @@ -172,16 +145,6 @@ def create end it 'does not register an offense when using `flash` before `redirect_back`' do - expect_no_offenses(<<~RUBY) - class HomeController < #{parent_class} - def create - flash[:alert] = "msg" if condition - - redirect_back fallback_location: root_path - end - end - RUBY - expect_no_offenses(<<~RUBY) class HomeController < #{parent_class} def create @@ -195,7 +158,7 @@ def create RUBY end - it 'registers an offense when using `flash` in multiline `if` branch before `render`' do + it 'registers an offense when using `flash` in multiline `if` branch before `render_to`' do expect_offense(<<~RUBY) class HomeController < #{parent_class} def create @@ -222,29 +185,6 @@ def create end end RUBY - - expect_offense(<<~RUBY) - class HomeController < #{parent_class} - def create - if condition - do_something - flash[:alert] = "msg" - ^^^^^ Use `flash.now` before `render`. - end - end - end - RUBY - - expect_correction(<<~RUBY) - class HomeController < #{parent_class} - def create - if condition - do_something - flash.now[:alert] = "msg" - end - end - end - RUBY end it 'does not register an offense when using `flash` in multiline `if` branch before `redirect_to`' do @@ -277,81 +217,6 @@ def create end end RUBY - - expect_no_offenses(<<~RUBY) - class HomeController < #{parent_class} - def create - if condition - flash[:alert] = "msg" - redirect_to :index - - return - end - end - end - RUBY - end - - it 'registers an offense when using `flash` in multiline `rescue` branch before `render`' do - expect_offense(<<~RUBY) - class HomeController < #{parent_class} - def create - begin - do_something - flash[:alert] = "msg in begin" - ^^^^^ Use `flash.now` before `render`. - rescue - flash[:alert] = "msg in rescue" - ^^^^^ Use `flash.now` before `render`. - end - - render :index - end - end - RUBY - - expect_correction(<<~RUBY) - class HomeController < #{parent_class} - def create - begin - do_something - flash.now[:alert] = "msg in begin" - rescue - flash.now[:alert] = "msg in rescue" - end - - render :index - end - end - RUBY - - expect_offense(<<~RUBY) - class HomeController < #{parent_class} - def create - begin - do_something - flash[:alert] = "msg in begin" - ^^^^^ Use `flash.now` before `render`. - rescue - flash[:alert] = "msg in rescue" - ^^^^^ Use `flash.now` before `render`. - end - end - end - RUBY - - expect_correction(<<~RUBY) - class HomeController < #{parent_class} - def create - begin - do_something - flash.now[:alert] = "msg in begin" - rescue - flash.now[:alert] = "msg in rescue" - end - end - end - RUBY end it 'does not register an offense when using `flash` in multiline `rescue` branch before `redirect_to`' do @@ -370,48 +235,6 @@ def create end RUBY end - - it 'does not register an offense when using `flash` before `redirect_to` in `rescue` branch' do - expect_no_offenses(<<~RUBY) - class HomeController < #{parent_class} - def create - begin - do_something - flash[:alert] = "msg in begin" - redirect_to :index - - return - rescue - flash[:alert] = "msg in rescue" - redirect_to :index - - return - end - - render :index - end - end - RUBY - - expect_no_offenses(<<~RUBY) - class HomeController < #{parent_class} - def create - begin - do_something - flash[:alert] = "msg in begin" - redirect_to :index - - return - rescue - flash[:alert] = "msg in rescue" - redirect_to :index - - return - end - end - end - RUBY - end end end @@ -505,4 +328,71 @@ def create RUBY end end + + context 'when using `flash` after `render` and `redirect_to` is used in implicit return branch ' \ + 'and render is is used in the other branch' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + class HomeController < ApplicationController + def create + if foo.update(params) + flash[:success] = 'msg' + + if redirect_to_index? + redirect_to index + else + redirect_to path(foo) + end + else + flash.now[:alert] = 'msg' + render :edit, status: :unprocessable_entity + end + end + end + RUBY + end + end + + context 'when using `flash` after `render` and `render` is part of a different preceding branch' \ + 'that implicitly returns' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + class HomeController < ApplicationController + def create + if remote_request? || sandbox? + if current_user.nil? + render :index + else + head :forbidden + end + elsif current_user.nil? + redirect_to sign_in_path + else + flash[:alert] = 'msg' + if request.referer.present? + redirect_to(request.referer) + else + redirect_to(root_path) + end + end + end + end + RUBY + end + end + + context 'when using `flash` in `rescue` and `redirect_to` in `ensure`' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + class HomeController < ApplicationController + def create + rescue + flash[:alert] = 'msg' + ensure + redirect_to :index + end + end + RUBY + end + end end From dbdee93776ae3df24d35ce5440c803b1efb52bda Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:30:50 +0200 Subject: [PATCH 08/23] [Fix #1343] False negatives for `Rails/EnumSyntax` I don't believe there is any issue with just looking at all value types. It just translates `foo: bar` into `:foo, bar`. Additionally, add `instance_methods` as a rails option. Not doing this would result autocorrect treating it as a enum column --- changelog/fix_false_negatives_enum_syntax.md | 1 + lib/rubocop/cop/rails/enum_syntax.rb | 26 +++++++---------- spec/rubocop/cop/rails/enum_syntax_spec.rb | 30 ++++++++++++++++++-- 3 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 changelog/fix_false_negatives_enum_syntax.md diff --git a/changelog/fix_false_negatives_enum_syntax.md b/changelog/fix_false_negatives_enum_syntax.md new file mode 100644 index 0000000000..b1d030fdf2 --- /dev/null +++ b/changelog/fix_false_negatives_enum_syntax.md @@ -0,0 +1 @@ +* [#1343](https://github.com/rubocop/rubocop-rails/issues/1343): Fix false negatives for `Rails/EnumSyntax` for non-literal mappings. ([@earlopain][]) diff --git a/lib/rubocop/cop/rails/enum_syntax.rb b/lib/rubocop/cop/rails/enum_syntax.rb index 39501c4331..9a36dadfef 100644 --- a/lib/rubocop/cop/rails/enum_syntax.rb +++ b/lib/rubocop/cop/rails/enum_syntax.rb @@ -24,7 +24,10 @@ class EnumSyntax < Base MSG = 'Enum defined with keyword arguments in `%s` enum declaration. Use positional arguments instead.' MSG_OPTIONS = 'Enum defined with deprecated options in `%s` enum declaration. Remove the `_` prefix.' RESTRICT_ON_SEND = %i[enum].freeze - OPTION_NAMES = %w[prefix suffix scopes default].freeze + + # From https://github.com/rails/rails/blob/v7.2.1/activerecord/lib/active_record/enum.rb#L231 + OPTION_NAMES = %w[prefix suffix scopes default instance_methods].freeze + UNDERSCORED_OPTION_NAMES = OPTION_NAMES.map { |option| "_#{option}" }.freeze def_node_matcher :enum?, <<~PATTERN (send nil? :enum (hash $...)) @@ -34,14 +37,6 @@ class EnumSyntax < Base (send nil? :enum $_ ${array hash} $_) PATTERN - def_node_matcher :enum_values, <<~PATTERN - (pair $_ ${array hash}) - PATTERN - - def_node_matcher :enum_options, <<~PATTERN - (pair $_ $_) - PATTERN - def on_send(node) check_and_correct_keyword_args(node) check_enum_options(node) @@ -52,10 +47,9 @@ def on_send(node) def check_and_correct_keyword_args(node) enum?(node) do |pairs| pairs.each do |pair| - key, values = enum_values(pair) - next unless key + next if option_key?(pair) - correct_keyword_args(node, key, values, pairs[1..]) + correct_keyword_args(node, pair.key, pair.value, pairs[1..]) end end end @@ -63,9 +57,7 @@ def check_and_correct_keyword_args(node) def check_enum_options(node) enum_with_options?(node) do |key, _, options| options.children.each do |option| - name, = enum_options(option) - - add_offense(name, message: format(MSG_OPTIONS, enum: enum_name_value(key))) if name.source[0] == '_' + add_offense(option.key, message: format(MSG_OPTIONS, enum: enum_name_value(key))) if option_key?(option) end end end @@ -107,6 +99,10 @@ def enum_name(elem) end end + def option_key?(pair) + UNDERSCORED_OPTION_NAMES.include?(pair.key.source) + end + def correct_options(options) corrected_options = options.map do |pair| name = if pair.key.source[0] == '_' diff --git a/spec/rubocop/cop/rails/enum_syntax_spec.rb b/spec/rubocop/cop/rails/enum_syntax_spec.rb index 2abf4e47fa..80c698cc05 100644 --- a/spec/rubocop/cop/rails/enum_syntax_spec.rb +++ b/spec/rubocop/cop/rails/enum_syntax_spec.rb @@ -82,6 +82,32 @@ end end + context 'when the enum name is underscored' do + it 'registers an offense' do + expect_offense(<<~RUBY) + enum :_key => { active: 0, archived: 1 }, _prefix: true + ^^^^^^^^^^^^^^^^^^^^^^^^^^ Enum defined with keyword arguments in `_key` enum declaration. Use positional arguments instead. + RUBY + + expect_correction(<<~RUBY) + enum :_key, { active: 0, archived: 1 }, prefix: true + RUBY + end + end + + context 'when the enum value is not a literal' do + it 'registers an offense' do + expect_offense(<<~RUBY) + enum key: %i[foo bar].map.with_index { |v, i| [v, i] }.to_h + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Enum defined with keyword arguments in `key` enum declaration. Use positional arguments instead. + RUBY + + expect_correction(<<~RUBY) + enum :key, %i[foo bar].map.with_index { |v, i| [v, i] }.to_h + RUBY + end + end + it 'autocorrects' do expect_offense(<<~RUBY) enum status: { active: 0, archived: 1 } @@ -95,12 +121,12 @@ it 'autocorrects options too' do expect_offense(<<~RUBY) - enum status: { active: 0, archived: 1 }, _prefix: true, _suffix: true, _default: :active, _scopes: true + enum status: { active: 0, archived: 1 }, _prefix: true, _suffix: true, _default: :active, _scopes: true, _instance_methods: true ^^^^^^^^^^^^^^^^^^^^^^^^^^ Enum defined with keyword arguments in `status` enum declaration. Use positional arguments instead. RUBY expect_correction(<<~RUBY) - enum :status, { active: 0, archived: 1 }, prefix: true, suffix: true, default: :active, scopes: true + enum :status, { active: 0, archived: 1 }, prefix: true, suffix: true, default: :active, scopes: true, instance_methods: true RUBY end end From 0a80131242a53569e6a96a996c86e65da2068320 Mon Sep 17 00:00:00 2001 From: fatkodima Date: Tue, 3 Sep 2024 19:24:27 +0300 Subject: [PATCH 09/23] Change `Rails/EnumSyntax` to autocorrect underscored options --- ...change_enum_syntax_to_autoccorect_underscored_options.md | 1 + lib/rubocop/cop/rails/enum_syntax.rb | 6 +++++- spec/rubocop/cop/rails/enum_syntax_spec.rb | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 changelog/change_enum_syntax_to_autoccorect_underscored_options.md diff --git a/changelog/change_enum_syntax_to_autoccorect_underscored_options.md b/changelog/change_enum_syntax_to_autoccorect_underscored_options.md new file mode 100644 index 0000000000..f497ea13de --- /dev/null +++ b/changelog/change_enum_syntax_to_autoccorect_underscored_options.md @@ -0,0 +1 @@ +* [#1350](https://github.com/rubocop/rubocop-rails/pull/1350): Change `Rails/EnumSyntax` to autocorrect underscored options. ([@fatkodima][]) diff --git a/lib/rubocop/cop/rails/enum_syntax.rb b/lib/rubocop/cop/rails/enum_syntax.rb index 9a36dadfef..a3d650440a 100644 --- a/lib/rubocop/cop/rails/enum_syntax.rb +++ b/lib/rubocop/cop/rails/enum_syntax.rb @@ -57,7 +57,11 @@ def check_and_correct_keyword_args(node) def check_enum_options(node) enum_with_options?(node) do |key, _, options| options.children.each do |option| - add_offense(option.key, message: format(MSG_OPTIONS, enum: enum_name_value(key))) if option_key?(option) + next unless option_key?(option) + + add_offense(option.key, message: format(MSG_OPTIONS, enum: enum_name_value(key))) do |corrector| + corrector.replace(option.key, option.key.source.delete_prefix('_')) + end end end end diff --git a/spec/rubocop/cop/rails/enum_syntax_spec.rb b/spec/rubocop/cop/rails/enum_syntax_spec.rb index 80c698cc05..9799fe66d1 100644 --- a/spec/rubocop/cop/rails/enum_syntax_spec.rb +++ b/spec/rubocop/cop/rails/enum_syntax_spec.rb @@ -47,12 +47,16 @@ end context 'with options prefixed with `_`' do - it 'registers an offense' do + it 'registers an offense and corrects' do expect_offense(<<~RUBY) enum :status, { active: 0, archived: 1 }, _prefix: true, _suffix: true ^^^^^^^ Enum defined with deprecated options in `status` enum declaration. Remove the `_` prefix. ^^^^^^^ Enum defined with deprecated options in `status` enum declaration. Remove the `_` prefix. RUBY + + expect_correction(<<~RUBY) + enum :status, { active: 0, archived: 1 }, prefix: true, suffix: true + RUBY end end From ff0759314dcb41009b96919d45ed12217a8d63ca Mon Sep 17 00:00:00 2001 From: fatkodima Date: Tue, 3 Sep 2024 19:05:58 +0300 Subject: [PATCH 10/23] Change `Rails/ApplicationRecord` to ignore migrations --- changelog/change_application_record_to_ignore_migrations.md | 1 + config/default.yml | 4 +++- lib/rubocop/cop/rails/application_record.rb | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changelog/change_application_record_to_ignore_migrations.md diff --git a/changelog/change_application_record_to_ignore_migrations.md b/changelog/change_application_record_to_ignore_migrations.md new file mode 100644 index 0000000000..59f8e2259d --- /dev/null +++ b/changelog/change_application_record_to_ignore_migrations.md @@ -0,0 +1 @@ +* [#1342](https://github.com/rubocop/rubocop-rails/issues/1342): Change `Rails/ApplicationRecord` to ignore migrations. ([@fatkodima][]) diff --git a/config/default.yml b/config/default.yml index 97b01498b0..74a0251182 100644 --- a/config/default.yml +++ b/config/default.yml @@ -212,7 +212,9 @@ Rails/ApplicationRecord: Enabled: true SafeAutoCorrect: false VersionAdded: '0.49' - VersionChanged: '2.5' + VersionChanged: '<>' + Exclude: + - db/**/*.rb Rails/ArelStar: Description: 'Enforces `Arel.star` instead of `"*"` for expanded columns.' diff --git a/lib/rubocop/cop/rails/application_record.rb b/lib/rubocop/cop/rails/application_record.rb index 91ee5e2aaf..f5f40bcdc2 100644 --- a/lib/rubocop/cop/rails/application_record.rb +++ b/lib/rubocop/cop/rails/application_record.rb @@ -5,6 +5,10 @@ module Cop module Rails # Checks that models subclass `ApplicationRecord` with Rails 5.0. # + # It is a common practice to define models inside migrations in order to retain forward + # compatibility by avoiding loading any application code. And so migration files are excluded + # by default for this cop. + # # @safety # This cop's autocorrection is unsafe because it may let the logic from `ApplicationRecord` # sneak into an Active Record model that is not purposed to inherit logic common among other From 5a0a69a5f0f81a59a514530424b032fde0f7bc97 Mon Sep 17 00:00:00 2001 From: masato-bkn <37011138+masato-bkn@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:29:53 +0900 Subject: [PATCH 11/23] Fix example in `Rails/PluralizationGrammar` --- lib/rubocop/cop/rails/pluralization_grammar.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rubocop/cop/rails/pluralization_grammar.rb b/lib/rubocop/cop/rails/pluralization_grammar.rb index beaaa8d736..4ee227b486 100644 --- a/lib/rubocop/cop/rails/pluralization_grammar.rb +++ b/lib/rubocop/cop/rails/pluralization_grammar.rb @@ -11,7 +11,7 @@ module Rails # 3.day.ago # 1.months.ago # 5.megabyte - # 1.gigabyte + # 1.gigabytes # # # good # 3.days.ago From 027db53f1778a11c57d2a4b8fd1c7833ddfc793a Mon Sep 17 00:00:00 2001 From: masato-bkn <37011138+masato-bkn@users.noreply.github.com> Date: Sat, 7 Sep 2024 12:15:20 +0900 Subject: [PATCH 12/23] Add missing tests for `Rails/CompactBlank` when receiver is a hash --- spec/rubocop/cop/rails/compact_blank_spec.rb | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/spec/rubocop/cop/rails/compact_blank_spec.rb b/spec/rubocop/cop/rails/compact_blank_spec.rb index 93d1ca2bd7..3b3cd9d77b 100644 --- a/spec/rubocop/cop/rails/compact_blank_spec.rb +++ b/spec/rubocop/cop/rails/compact_blank_spec.rb @@ -24,6 +24,17 @@ RUBY end + it 'registers and corrects an offense when using `reject { |k, v| v.blank? }`' do + expect_offense(<<~RUBY) + collection.reject { |k, v| v.blank? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank + RUBY + end + it 'registers and corrects an offense when using `delete_if { |e| e.blank? }`' do expect_offense(<<~RUBY) collection.delete_if { |e| e.blank? } @@ -46,6 +57,17 @@ RUBY end + it 'registers and corrects an offense when using `delete_if { |k, v| v.blank? }`' do + expect_offense(<<~RUBY) + collection.delete_if { |k, v| v.blank? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank!` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank! + RUBY + end + it 'does not registers an offense when using `reject! { |e| e.blank? }`' do expect_no_offenses(<<~RUBY) collection.reject! { |e| e.blank? } @@ -91,6 +113,17 @@ RUBY end + it 'registers and corrects an offense when using `select { |k, v| v.present? }`' do + expect_offense(<<~RUBY) + collection.select { |k, v| v.present? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank + RUBY + end + it 'registers and corrects an offense when using `keep_if { |e| e.present? }`' do expect_offense(<<~RUBY) collection.keep_if { |e| e.present? } @@ -113,6 +146,17 @@ RUBY end + it 'registers and corrects an offense when using `keep_if { |k, v| v.present? }`' do + expect_offense(<<~RUBY) + collection.keep_if { |k, v| v.present? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank!` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank! + RUBY + end + it 'does not register an offense when using `select! { |e| e.present? }`' do expect_no_offenses(<<~RUBY) collection.select! { |e| e.present? } From 22bc59e3a0c6991dfc771ebe9b4c2c4e868e3d20 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 7 Sep 2024 17:06:43 +0900 Subject: [PATCH 13/23] Update Changelog --- CHANGELOG.md | 10 ++++++++++ .../change_application_record_to_ignore_migrations.md | 1 - ...e_enum_syntax_to_autoccorect_underscored_options.md | 1 - changelog/fix_false_negatives_enum_syntax.md | 1 - changelog/fix_false_positive_database_qualified.md | 1 - 5 files changed, 10 insertions(+), 4 deletions(-) delete mode 100644 changelog/change_application_record_to_ignore_migrations.md delete mode 100644 changelog/change_enum_syntax_to_autoccorect_underscored_options.md delete mode 100644 changelog/fix_false_negatives_enum_syntax.md delete mode 100644 changelog/fix_false_positive_database_qualified.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 8671e1bf72..f4ef61d35a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ ## master (unreleased) +### Bug fixes + +* [#1343](https://github.com/rubocop/rubocop-rails/issues/1343): Fix false negatives for `Rails/EnumSyntax` for non-literal mappings. ([@earlopain][]) +* [#1340](https://github.com/rubocop/rubocop-rails/issues/1340): Fix a false positive for `Rails/WhereEquals`, `Rails/WhereNot`, and `Rails/WhereRange` when qualifying the database name. ([@earlopain][]) + +### Changes + +* [#1342](https://github.com/rubocop/rubocop-rails/issues/1342): Change `Rails/ApplicationRecord` to ignore migrations. ([@fatkodima][]) +* [#1350](https://github.com/rubocop/rubocop-rails/pull/1350): Change `Rails/EnumSyntax` to autocorrect underscored options. ([@fatkodima][]) + ## 2.26.0 (2024-08-24) ### New features diff --git a/changelog/change_application_record_to_ignore_migrations.md b/changelog/change_application_record_to_ignore_migrations.md deleted file mode 100644 index 59f8e2259d..0000000000 --- a/changelog/change_application_record_to_ignore_migrations.md +++ /dev/null @@ -1 +0,0 @@ -* [#1342](https://github.com/rubocop/rubocop-rails/issues/1342): Change `Rails/ApplicationRecord` to ignore migrations. ([@fatkodima][]) diff --git a/changelog/change_enum_syntax_to_autoccorect_underscored_options.md b/changelog/change_enum_syntax_to_autoccorect_underscored_options.md deleted file mode 100644 index f497ea13de..0000000000 --- a/changelog/change_enum_syntax_to_autoccorect_underscored_options.md +++ /dev/null @@ -1 +0,0 @@ -* [#1350](https://github.com/rubocop/rubocop-rails/pull/1350): Change `Rails/EnumSyntax` to autocorrect underscored options. ([@fatkodima][]) diff --git a/changelog/fix_false_negatives_enum_syntax.md b/changelog/fix_false_negatives_enum_syntax.md deleted file mode 100644 index b1d030fdf2..0000000000 --- a/changelog/fix_false_negatives_enum_syntax.md +++ /dev/null @@ -1 +0,0 @@ -* [#1343](https://github.com/rubocop/rubocop-rails/issues/1343): Fix false negatives for `Rails/EnumSyntax` for non-literal mappings. ([@earlopain][]) diff --git a/changelog/fix_false_positive_database_qualified.md b/changelog/fix_false_positive_database_qualified.md deleted file mode 100644 index 50e815b818..0000000000 --- a/changelog/fix_false_positive_database_qualified.md +++ /dev/null @@ -1 +0,0 @@ -* [#1340](https://github.com/rubocop/rubocop-rails/issues/1340): Fix a false positive for `Rails/WhereEquals`, `Rails/WhereNot`, and `Rails/WhereRange` when qualifying the database name. ([@earlopain][]) From 6d6fca2e6fc6e4c4d0785c09538b59f8f55a5f6c Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 7 Sep 2024 17:07:14 +0900 Subject: [PATCH 14/23] Cut 2.26.1 --- CHANGELOG.md | 2 ++ config/default.yml | 2 +- docs/antora.yml | 2 +- docs/modules/ROOT/pages/cops_rails.adoc | 21 +++++++++++++++++++-- lib/rubocop/rails/version.rb | 2 +- relnotes/v2.26.1.md | 12 ++++++++++++ 6 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 relnotes/v2.26.1.md diff --git a/CHANGELOG.md b/CHANGELOG.md index f4ef61d35a..ae1c5d800e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ ## master (unreleased) +## 2.26.1 (2024-09-07) + ### Bug fixes * [#1343](https://github.com/rubocop/rubocop-rails/issues/1343): Fix false negatives for `Rails/EnumSyntax` for non-literal mappings. ([@earlopain][]) diff --git a/config/default.yml b/config/default.yml index 74a0251182..b59db897c5 100644 --- a/config/default.yml +++ b/config/default.yml @@ -212,7 +212,7 @@ Rails/ApplicationRecord: Enabled: true SafeAutoCorrect: false VersionAdded: '0.49' - VersionChanged: '<>' + VersionChanged: '2.26' Exclude: - db/**/*.rb diff --git a/docs/antora.yml b/docs/antora.yml index 9e0ff48acb..0e3477f379 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop-rails title: RuboCop Rails # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: ~ +version: '2.26' nav: - modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/pages/cops_rails.adoc b/docs/modules/ROOT/pages/cops_rails.adoc index b946879608..ad89ca7c52 100644 --- a/docs/modules/ROOT/pages/cops_rails.adoc +++ b/docs/modules/ROOT/pages/cops_rails.adoc @@ -612,11 +612,15 @@ end | Yes | Always (Unsafe) | 0.49 -| 2.5 +| 2.26 |=== Checks that models subclass `ApplicationRecord` with Rails 5.0. +It is a common practice to define models inside migrations in order to retain forward +compatibility by avoiding loading any application code. And so migration files are excluded +by default for this cop. + === Safety This cop's autocorrection is unsafe because it may let the logic from `ApplicationRecord` @@ -638,6 +642,16 @@ class Rails4Model < ActiveRecord::Base end ---- +=== Configurable attributes + +|=== +| Name | Default value | Configurable values + +| Exclude +| `+db/**/*.rb+` +| Array +|=== + == Rails/ArelStar |=== @@ -4178,7 +4192,7 @@ core extensions to the numeric classes. 3.day.ago 1.months.ago 5.megabyte -1.gigabyte +1.gigabytes # good 3.days.ago @@ -5458,6 +5472,8 @@ File.read(Rails.root.join('db', 'schema.rb')) File.binread(Rails.root.join('db', 'schema.rb')) File.write(Rails.root.join('db', 'schema.rb'), content) File.binwrite(Rails.root.join('db', 'schema.rb'), content) +Dir.glob(Rails.root.join('db', 'schema.rb')) +Dir[Rails.root.join('db', 'schema.rb')] # good Rails.root.join('db', 'schema.rb').open @@ -5466,6 +5482,7 @@ Rails.root.join('db', 'schema.rb').read Rails.root.join('db', 'schema.rb').binread Rails.root.join('db', 'schema.rb').write(content) Rails.root.join('db', 'schema.rb').binwrite(content) +Rails.root.glob("db/schema.rb") ---- == Rails/RootPublicPath diff --git a/lib/rubocop/rails/version.rb b/lib/rubocop/rails/version.rb index 438e0a2245..c77f1c36d1 100644 --- a/lib/rubocop/rails/version.rb +++ b/lib/rubocop/rails/version.rb @@ -4,7 +4,7 @@ module RuboCop module Rails # This module holds the RuboCop Rails version information. module Version - STRING = '2.26.0' + STRING = '2.26.1' def self.document_version STRING.match('\d+\.\d+').to_s diff --git a/relnotes/v2.26.1.md b/relnotes/v2.26.1.md new file mode 100644 index 0000000000..4a0505bc57 --- /dev/null +++ b/relnotes/v2.26.1.md @@ -0,0 +1,12 @@ +### Bug fixes + +* [#1343](https://github.com/rubocop/rubocop-rails/issues/1343): Fix false negatives for `Rails/EnumSyntax` for non-literal mappings. ([@earlopain][]) +* [#1340](https://github.com/rubocop/rubocop-rails/issues/1340): Fix a false positive for `Rails/WhereEquals`, `Rails/WhereNot`, and `Rails/WhereRange` when qualifying the database name. ([@earlopain][]) + +### Changes + +* [#1342](https://github.com/rubocop/rubocop-rails/issues/1342): Change `Rails/ApplicationRecord` to ignore migrations. ([@fatkodima][]) +* [#1350](https://github.com/rubocop/rubocop-rails/pull/1350): Change `Rails/EnumSyntax` to autocorrect underscored options. ([@fatkodima][]) + +[@earlopain]: https://github.com/earlopain +[@fatkodima]: https://github.com/fatkodima From ebf1762cf09d7033c385cdc99f1cf4f9ccc3273b Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 7 Sep 2024 17:15:32 +0900 Subject: [PATCH 15/23] Switch back docs version to master --- docs/antora.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/antora.yml b/docs/antora.yml index 0e3477f379..9e0ff48acb 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop-rails title: RuboCop Rails # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: '2.26' +version: ~ nav: - modules/ROOT/nav.adoc From cbb7257a4fdcd1378c5fe02149b48982bc9f41dc Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Mon, 9 Sep 2024 13:17:08 +0900 Subject: [PATCH 16/23] [Doc] Update the "Rails configuration tip" section Follow up https://github.com/rails/rails/pull/50506. --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index adbf9a5464..b8d01488ca 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ end ## Rails configuration tip -If you are using Rails 6.1 or newer, add the following `config.generators.after_generate` setting to +In Rails 6.1+, add the following `config.generators.after_generate` setting to your `config/environments/development.rb` to apply RuboCop autocorrection to code generated by `bin/rails g`. ```ruby @@ -84,6 +84,20 @@ It uses `rubocop -A` to apply `Style/FrozenStringLiteralComment` and other unsaf `rubocop -A` is unsafe autocorrection, but code generated by default is simple and less likely to be incompatible with `rubocop -A`. If you have problems you can replace it with `rubocop -a` instead. +In Rails 7.2+, it is recommended to use `config.generators.apply_rubocop_autocorrect_after_generate!` instead of the above setting: + +```diff + # config/environments/development.rb + Rails.application.configure do + (snip) + # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. +- # config.generators.apply_rubocop_autocorrect_after_generate! ++ config.generators.apply_rubocop_autocorrect_after_generate! + end +``` + +You only need to uncomment. + ## The Cops All cops are located under From 9980211e21c78ec6c6a529e9bd1ec691732840bd Mon Sep 17 00:00:00 2001 From: masato-bkn <37011138+masato-bkn@users.noreply.github.com> Date: Sun, 8 Sep 2024 15:39:13 +0900 Subject: [PATCH 17/23] Support `filter` in `Rails/CompactBlank` --- ...e_support_filter_in_rails_compact_blank.md | 1 + lib/rubocop/cop/rails/compact_blank.rb | 11 ++-- spec/rubocop/cop/rails/compact_blank_spec.rb | 57 +++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 changelog/change_support_filter_in_rails_compact_blank.md diff --git a/changelog/change_support_filter_in_rails_compact_blank.md b/changelog/change_support_filter_in_rails_compact_blank.md new file mode 100644 index 0000000000..a439c69a02 --- /dev/null +++ b/changelog/change_support_filter_in_rails_compact_blank.md @@ -0,0 +1 @@ +* [#1359](https://github.com/rubocop/rubocop-rails/pull/1359): Support `filter` in `Rails/CompactBlank`. ([@masato-bkn][]) diff --git a/lib/rubocop/cop/rails/compact_blank.rb b/lib/rubocop/cop/rails/compact_blank.rb index a6f0f0860a..5b3535cf76 100644 --- a/lib/rubocop/cop/rails/compact_blank.rb +++ b/lib/rubocop/cop/rails/compact_blank.rb @@ -25,6 +25,8 @@ module Rails # collection.reject { |_k, v| v.blank? } # collection.select(&:present?) # collection.select { |_k, v| v.present? } + # collection.filter(&:present?) + # collection.filter { |_k, v| v.present? } # # # good # collection.compact_blank @@ -44,7 +46,8 @@ class CompactBlank < Base extend TargetRailsVersion MSG = 'Use `%s` instead.' - RESTRICT_ON_SEND = %i[reject delete_if select keep_if].freeze + RESTRICT_ON_SEND = %i[reject delete_if select filter keep_if].freeze + DESTRUCTIVE_METHODS = %i[delete_if keep_if].freeze minimum_target_rails_version 6.1 @@ -64,14 +67,14 @@ class CompactBlank < Base def_node_matcher :select_with_block?, <<~PATTERN (block - (send _ {:select :keep_if}) + (send _ {:select :filter :keep_if}) $(args ...) (send $(lvar _) :present?)) PATTERN def_node_matcher :select_with_block_pass?, <<~PATTERN - (send _ {:select :keep_if} + (send _ {:select :filter :keep_if} (block-pass (sym :present?))) PATTERN @@ -120,7 +123,7 @@ def offense_range(node) end def preferred_method(node) - node.method?(:reject) || node.method?(:select) ? 'compact_blank' : 'compact_blank!' + DESTRUCTIVE_METHODS.include?(node.method_name) ? 'compact_blank!' : 'compact_blank' end end end diff --git a/spec/rubocop/cop/rails/compact_blank_spec.rb b/spec/rubocop/cop/rails/compact_blank_spec.rb index 3b3cd9d77b..e89d7f3eca 100644 --- a/spec/rubocop/cop/rails/compact_blank_spec.rb +++ b/spec/rubocop/cop/rails/compact_blank_spec.rb @@ -124,6 +124,39 @@ RUBY end + it 'registers and corrects an offense when using `filter { |e| e.present? }`' do + expect_offense(<<~RUBY) + collection.filter { |e| e.present? } + ^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank + RUBY + end + + it 'registers and corrects an offense when using `filter(&:present?)`' do + expect_offense(<<~RUBY) + collection.filter(&:present?) + ^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank + RUBY + end + + it 'registers and corrects an offense when using `filter { |k, v| v.present? }`' do + expect_offense(<<~RUBY) + collection.filter { |k, v| v.present? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank + RUBY + end + it 'registers and corrects an offense when using `keep_if { |e| e.present? }`' do expect_offense(<<~RUBY) collection.keep_if { |e| e.present? } @@ -169,6 +202,18 @@ RUBY end + it 'does not register an offense when using `filter! { |e| e.present? }`' do + expect_no_offenses(<<~RUBY) + collection.filter! { |e| e.present? } + RUBY + end + + it 'does not register an offense when using `filter!(&:present?)`' do + expect_no_offenses(<<~RUBY) + collection.filter!(&:present?) + RUBY + end + it 'does not register an offense when using `compact_blank`' do expect_no_offenses(<<~RUBY) collection.compact_blank @@ -206,6 +251,12 @@ def foo(arg) collection.select { |e| e.blank? } RUBY end + + it 'does not register an offense when using `filter { |e| e.blank? }`' do + expect_no_offenses(<<~RUBY) + collection.filter { |e| e.blank? } + RUBY + end end context 'Rails <= 6.0', :rails60 do @@ -226,5 +277,11 @@ def foo(arg) collection.select { |e| e.present? } RUBY end + + it 'does not register an offense when using `filter { |e| e.present? }`' do + expect_no_offenses(<<~RUBY) + collection.filter { |e| e.present? } + RUBY + end end end From f4f3bf13a3433a1223e675d1954ac8ad74d96eca Mon Sep 17 00:00:00 2001 From: masato-bkn <37011138+masato-bkn@users.noreply.github.com> Date: Wed, 11 Sep 2024 22:02:52 +0900 Subject: [PATCH 18/23] Fix `Rails/CompactBlank` to avoid reporting offense for `filter` in Ruby versions below 2.6 --- lib/rubocop/cop/rails/compact_blank.rb | 1 + spec/rubocop/cop/rails/compact_blank_spec.rb | 21 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/rubocop/cop/rails/compact_blank.rb b/lib/rubocop/cop/rails/compact_blank.rb index 5b3535cf76..636faf5084 100644 --- a/lib/rubocop/cop/rails/compact_blank.rb +++ b/lib/rubocop/cop/rails/compact_blank.rb @@ -80,6 +80,7 @@ class CompactBlank < Base PATTERN def on_send(node) + return if target_ruby_version < 2.6 && node.method?(:filter) return unless bad_method?(node) range = offense_range(node) diff --git a/spec/rubocop/cop/rails/compact_blank_spec.rb b/spec/rubocop/cop/rails/compact_blank_spec.rb index e89d7f3eca..75937de4ee 100644 --- a/spec/rubocop/cop/rails/compact_blank_spec.rb +++ b/spec/rubocop/cop/rails/compact_blank_spec.rb @@ -257,6 +257,27 @@ def foo(arg) collection.filter { |e| e.blank? } RUBY end + + context 'target_ruby_version >= 2.6', :ruby26 do + it 'registers and corrects an offense when using `filter { |e| e.present? }`' do + expect_offense(<<~RUBY) + collection.filter { |e| e.present? } + ^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank + RUBY + end + end + + context 'target_ruby_version < 2.6', :ruby25, unsupported_on: :prism do + it 'does not register an offense when using `filter { |e| e.present? }`' do + expect_no_offenses(<<~RUBY) + collection.filter { |e| e.present? } + RUBY + end + end end context 'Rails <= 6.0', :rails60 do From 50fe9a72fd1fa2012b05c1c2909427bf762760a0 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 12 Sep 2024 12:30:58 +0900 Subject: [PATCH 19/23] [Fix #1362] Fix false positives for `Rails/EnumSyntax` Fixes #1362. This PR fixes false positives for `Rails/EnumSyntax` when using Ruby 2.7. The warning shown in https://github.com/rubocop/rubocop-rails/issues/1238 appears starting from Rails 7.2 (Requires Ruby 3.1+). On the other hand, if users use Ruby 2.7, the warning reported in https://github.com/rubocop/rubocop-rails/issues/1362 will be displayed. Therefore, it would be appropriate to enable this cop only when analyzing Ruby 3.0+. Nothing will happen when using Ruby 2.7 with Rails 7.0 or Rails 7.1, but the warning in https://github.com/rubocop/rubocop-rails/issues/1238 will not be displayed either. Meanwhile, in Rails 7.2, which requires Ruby 3.1+, Ruby 2.7 cannot be used, so there is no issue. --- .../fix_false_positives_for_rails_enum_syntax.md | 1 + lib/rubocop/cop/rails/enum_syntax.rb | 2 ++ spec/rubocop/cop/rails/enum_syntax_spec.rb | 14 +++++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_false_positives_for_rails_enum_syntax.md diff --git a/changelog/fix_false_positives_for_rails_enum_syntax.md b/changelog/fix_false_positives_for_rails_enum_syntax.md new file mode 100644 index 0000000000..914d96ff49 --- /dev/null +++ b/changelog/fix_false_positives_for_rails_enum_syntax.md @@ -0,0 +1 @@ +* [#1362](https://github.com/rubocop/rubocop-rails/issues/1362): Fix false positives for `Rails/EnumSyntax` when using Ruby 2.7. ([@koic][]) diff --git a/lib/rubocop/cop/rails/enum_syntax.rb b/lib/rubocop/cop/rails/enum_syntax.rb index a3d650440a..5b3d683916 100644 --- a/lib/rubocop/cop/rails/enum_syntax.rb +++ b/lib/rubocop/cop/rails/enum_syntax.rb @@ -17,8 +17,10 @@ module Rails # class EnumSyntax < Base extend AutoCorrector + extend TargetRubyVersion extend TargetRailsVersion + minimum_target_ruby_version 3.0 minimum_target_rails_version 7.0 MSG = 'Enum defined with keyword arguments in `%s` enum declaration. Use positional arguments instead.' diff --git a/spec/rubocop/cop/rails/enum_syntax_spec.rb b/spec/rubocop/cop/rails/enum_syntax_spec.rb index 9799fe66d1..b5f20a2436 100644 --- a/spec/rubocop/cop/rails/enum_syntax_spec.rb +++ b/spec/rubocop/cop/rails/enum_syntax_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe RuboCop::Cop::Rails::EnumSyntax, :config do - context 'Rails >= 7.0', :rails70 do + context 'Rails >= 7.0 and Ruby >= 3.0', :rails70, :ruby30 do context 'when keyword arguments are used' do context 'with %i[] syntax' do it 'registers an offense' do @@ -148,6 +148,18 @@ end end + context 'Rails >= 7.0 and Ruby <= 2.7', :rails70, :ruby27, unsupported_on: :prism do + context 'when keyword arguments are used' do + context 'with %i[] syntax' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + enum status: %i[active archived], _prefix: true + RUBY + end + end + end + end + context 'Rails <= 6.1', :rails61 do context 'when keyword arguments are used' do context 'with %i[] syntax' do From 38cec18985618f9879d7308b37af0f8100c35f1a Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 14 Sep 2024 05:09:07 +0900 Subject: [PATCH 20/23] [Doc] Sync the Rails configuration tip with the README --- docs/modules/ROOT/pages/usage.adoc | 32 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/docs/modules/ROOT/pages/usage.adoc b/docs/modules/ROOT/pages/usage.adoc index 1b68c110d4..97cfe75cec 100644 --- a/docs/modules/ROOT/pages/usage.adoc +++ b/docs/modules/ROOT/pages/usage.adoc @@ -33,18 +33,17 @@ end == Rails configuration tip -If you are using Rails 6.1 or newer, add the following `config.generators.after_generate` setting to -your config/application.rb to apply RuboCop autocorrection to code generated by `bin/rails g`. +In Rails 6.1+, add the following `config.generators.after_generate` setting to +your `config/environments/development.rb` to apply RuboCop autocorrection to code generated by `bin/rails g`. [source,ruby] ---- -module YourCoolApp - class Application < Rails::Application - config.generators.after_generate do |files| - parsable_files = files.filter { |file| File.exist?(file) && file.end_with?('.rb') } - unless parsable_files.empty? - system("bundle exec rubocop -A --fail-level=E #{parsable_files.shelljoin}", exception: true) - end +# config/environments/development.rb +Rails.application.configure do + config.generators.after_generate do |files| + parsable_files = files.filter { |file| file.end_with?('.rb') } + unless parsable_files.empty? + system("bundle exec rubocop -A --fail-level=E #{parsable_files.shelljoin}", exception: true) end end end @@ -53,3 +52,18 @@ end It uses `rubocop -A` to apply `Style/FrozenStringLiteralComment` and other unsafe autocorrection cops. `rubocop -A` is unsafe autocorrection, but code generated by default is simple and less likely to be incompatible with `rubocop -A`. If you have problems you can replace it with `rubocop -a` instead. + +In Rails 7.2+, it is recommended to use `config.generators.apply_rubocop_autocorrect_after_generate!` instead of the above setting: + +[source,diff] +---- + # config/environments/development.rb + Rails.application.configure do + (snip) + # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. +- # config.generators.apply_rubocop_autocorrect_after_generate! ++ config.generators.apply_rubocop_autocorrect_after_generate! + end +---- + +You only need to uncomment. From f935a0b8a1ddbc8e651e689293609dce39ada5d3 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 18 Sep 2024 01:10:42 +0900 Subject: [PATCH 21/23] Suppress new RuboCop offenses Follow up https://github.com/rubocop/rubocop/pull/13242 This commit removes the following redundant `source_range` to suppress new RuboCop offenses: ```console $ bundle exec rake (snip) Offenses: lib/rubocop/cop/rails/redundant_foreign_key.rb:43:44: C: [Corrected] InternalAffairs/RedundantSourceRange: Remove the redundant source_range. add_offense(foreign_key_pair.source_range) do |corrector| ^^^^^^^^^^^^ lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb:81:34: C: [Corrected] InternalAffairs/RedundantSourceRange: Remove the redundant source_range. add_offense(receiver.source_range) do |corrector| ^^^^^^^^^^^^ lib/rubocop/cop/rails/reflection_class_name.rb:46:47: C: [Corrected] InternalAffairs/RedundantSourceRange: Remove the redundant source_range. add_offense(reflection_class_name.source_range) do |corrector| ^^^^^^^^^^^^ lib/rubocop/cop/rails/request_referer.rb:37:30: C: [Corrected] InternalAffairs/RedundantSourceRange: Remove the redundant source_range. add_offense(node.source_range) do |corrector| ^^^^^^^^^^^^ 296 files inspected, 4 offenses detected, 4 offenses corrected ``` --- lib/rubocop/cop/rails/redundant_foreign_key.rb | 2 +- lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb | 2 +- lib/rubocop/cop/rails/reflection_class_name.rb | 2 +- lib/rubocop/cop/rails/request_referer.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/rubocop/cop/rails/redundant_foreign_key.rb b/lib/rubocop/cop/rails/redundant_foreign_key.rb index 3026fca294..f1f1e336fb 100644 --- a/lib/rubocop/cop/rails/redundant_foreign_key.rb +++ b/lib/rubocop/cop/rails/redundant_foreign_key.rb @@ -40,7 +40,7 @@ class RedundantForeignKey < Base def on_send(node) association_with_foreign_key(node) do |type, name, options, foreign_key_pair, foreign_key| if redundant?(node, type, name, options, foreign_key) - add_offense(foreign_key_pair.source_range) do |corrector| + add_offense(foreign_key_pair) do |corrector| range = range_with_surrounding_space(foreign_key_pair.source_range, side: :left) range = range_with_surrounding_comma(range, :left) diff --git a/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb b/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb index 62d52786cf..05df3c8675 100644 --- a/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +++ b/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb @@ -78,7 +78,7 @@ def on_block(node) send_nodes.each do |send_node| receiver = send_node.receiver - add_offense(receiver.source_range) do |corrector| + add_offense(receiver) do |corrector| autocorrect(corrector, send_node, node) end end diff --git a/lib/rubocop/cop/rails/reflection_class_name.rb b/lib/rubocop/cop/rails/reflection_class_name.rb index d0afa1acb6..8393956b83 100644 --- a/lib/rubocop/cop/rails/reflection_class_name.rb +++ b/lib/rubocop/cop/rails/reflection_class_name.rb @@ -43,7 +43,7 @@ def on_send(node) return if reflection_class_name.value.send_type? && reflection_class_name.value.receiver.nil? return if reflection_class_name.value.lvar_type? && str_assigned?(reflection_class_name) - add_offense(reflection_class_name.source_range) do |corrector| + add_offense(reflection_class_name) do |corrector| autocorrect(corrector, reflection_class_name) end end diff --git a/lib/rubocop/cop/rails/request_referer.rb b/lib/rubocop/cop/rails/request_referer.rb index 38a68d8099..980064b884 100644 --- a/lib/rubocop/cop/rails/request_referer.rb +++ b/lib/rubocop/cop/rails/request_referer.rb @@ -34,7 +34,7 @@ def on_send(node) referer?(node) do return unless node.method?(wrong_method_name) - add_offense(node.source_range) do |corrector| + add_offense(node) do |corrector| corrector.replace(node, "request.#{style}") end end From a451135c12b118ae88bfe6b56adef14714190d41 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 21 Sep 2024 12:48:36 +0900 Subject: [PATCH 22/23] Update Changelog --- CHANGELOG.md | 10 ++++++++++ .../change_support_filter_in_rails_compact_blank.md | 1 - changelog/fix_false_positives_for_rails_enum_syntax.md | 1 - changelog/fix_revert_flash_before_render.md | 1 - changelog/fix_wrong_autocorrect_for_rails_file_path.md | 1 - 5 files changed, 10 insertions(+), 4 deletions(-) delete mode 100644 changelog/change_support_filter_in_rails_compact_blank.md delete mode 100644 changelog/fix_false_positives_for_rails_enum_syntax.md delete mode 100644 changelog/fix_revert_flash_before_render.md delete mode 100644 changelog/fix_wrong_autocorrect_for_rails_file_path.md diff --git a/CHANGELOG.md b/CHANGELOG.md index ae1c5d800e..f995c19ac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ ## master (unreleased) +### Bug fixes + +* [#1362](https://github.com/rubocop/rubocop-rails/issues/1362): Fix false positives for `Rails/EnumSyntax` when using Ruby 2.7. ([@koic][]) +* [#1269](https://github.com/rubocop/rubocop-rails/issues/1269): Fix false positives for `Rails/ActionControllerFlashBeforeRender` in combination with implicit returns. ([@earlopain][]) +* [#1326](https://github.com/rubocop/rubocop-rails/pull/1326): Fix wrong autocorrect for `Rails/FilePath` when passing an array to `File.join`. ([@earlopain][]) + +### Changes + +* [#1359](https://github.com/rubocop/rubocop-rails/pull/1359): Support `filter` in `Rails/CompactBlank`. ([@masato-bkn][]) + ## 2.26.1 (2024-09-07) ### Bug fixes diff --git a/changelog/change_support_filter_in_rails_compact_blank.md b/changelog/change_support_filter_in_rails_compact_blank.md deleted file mode 100644 index a439c69a02..0000000000 --- a/changelog/change_support_filter_in_rails_compact_blank.md +++ /dev/null @@ -1 +0,0 @@ -* [#1359](https://github.com/rubocop/rubocop-rails/pull/1359): Support `filter` in `Rails/CompactBlank`. ([@masato-bkn][]) diff --git a/changelog/fix_false_positives_for_rails_enum_syntax.md b/changelog/fix_false_positives_for_rails_enum_syntax.md deleted file mode 100644 index 914d96ff49..0000000000 --- a/changelog/fix_false_positives_for_rails_enum_syntax.md +++ /dev/null @@ -1 +0,0 @@ -* [#1362](https://github.com/rubocop/rubocop-rails/issues/1362): Fix false positives for `Rails/EnumSyntax` when using Ruby 2.7. ([@koic][]) diff --git a/changelog/fix_revert_flash_before_render.md b/changelog/fix_revert_flash_before_render.md deleted file mode 100644 index 4a7cab0316..0000000000 --- a/changelog/fix_revert_flash_before_render.md +++ /dev/null @@ -1 +0,0 @@ -* [#1269](https://github.com/rubocop/rubocop-rails/issues/1269): Fix false positives for `Rails/ActionControllerFlashBeforeRender` in combination with implicit returns. ([@earlopain][]) diff --git a/changelog/fix_wrong_autocorrect_for_rails_file_path.md b/changelog/fix_wrong_autocorrect_for_rails_file_path.md deleted file mode 100644 index 10b2da3ae5..0000000000 --- a/changelog/fix_wrong_autocorrect_for_rails_file_path.md +++ /dev/null @@ -1 +0,0 @@ -* [#1326](https://github.com/rubocop/rubocop-rails/pull/1326): Fix wrong autocorrect for `Rails/FilePath` when passing an array to `File.join`. ([@earlopain][]) From f646d6e10aa5b6997b410bd59d1e1168646c3dce Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 21 Sep 2024 12:48:50 +0900 Subject: [PATCH 23/23] Cut 2.26.2 --- CHANGELOG.md | 2 ++ docs/antora.yml | 2 +- docs/modules/ROOT/pages/cops_rails.adoc | 4 ++++ lib/rubocop/rails/version.rb | 2 +- relnotes/v2.26.2.md | 13 +++++++++++++ 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 relnotes/v2.26.2.md diff --git a/CHANGELOG.md b/CHANGELOG.md index f995c19ac6..13df636ab8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ ## master (unreleased) +## 2.26.2 (2024-09-21) + ### Bug fixes * [#1362](https://github.com/rubocop/rubocop-rails/issues/1362): Fix false positives for `Rails/EnumSyntax` when using Ruby 2.7. ([@koic][]) diff --git a/docs/antora.yml b/docs/antora.yml index 9e0ff48acb..0e3477f379 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop-rails title: RuboCop Rails # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: ~ +version: '2.26' nav: - modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/pages/cops_rails.adoc b/docs/modules/ROOT/pages/cops_rails.adoc index ad89ca7c52..b9892b58eb 100644 --- a/docs/modules/ROOT/pages/cops_rails.adoc +++ b/docs/modules/ROOT/pages/cops_rails.adoc @@ -1109,6 +1109,8 @@ collection.reject(&:blank?) collection.reject { |_k, v| v.blank? } collection.select(&:present?) collection.select { |_k, v| v.present? } +collection.filter(&:present?) +collection.filter { |_k, v| v.present? } # good collection.compact_blank @@ -1925,6 +1927,8 @@ enum status: { active: 0, archived: 1 } == Rails/EnumSyntax +NOTE: Required Ruby version: 3.0 + |=== | Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed diff --git a/lib/rubocop/rails/version.rb b/lib/rubocop/rails/version.rb index c77f1c36d1..15095dece0 100644 --- a/lib/rubocop/rails/version.rb +++ b/lib/rubocop/rails/version.rb @@ -4,7 +4,7 @@ module RuboCop module Rails # This module holds the RuboCop Rails version information. module Version - STRING = '2.26.1' + STRING = '2.26.2' def self.document_version STRING.match('\d+\.\d+').to_s diff --git a/relnotes/v2.26.2.md b/relnotes/v2.26.2.md new file mode 100644 index 0000000000..93e5c7a53b --- /dev/null +++ b/relnotes/v2.26.2.md @@ -0,0 +1,13 @@ +### Bug fixes + +* [#1362](https://github.com/rubocop/rubocop-rails/issues/1362): Fix false positives for `Rails/EnumSyntax` when using Ruby 2.7. ([@koic][]) +* [#1269](https://github.com/rubocop/rubocop-rails/issues/1269): Fix false positives for `Rails/ActionControllerFlashBeforeRender` in combination with implicit returns. ([@earlopain][]) +* [#1326](https://github.com/rubocop/rubocop-rails/pull/1326): Fix wrong autocorrect for `Rails/FilePath` when passing an array to `File.join`. ([@earlopain][]) + +### Changes + +* [#1359](https://github.com/rubocop/rubocop-rails/pull/1359): Support `filter` in `Rails/CompactBlank`. ([@masato-bkn][]) + +[@koic]: https://github.com/koic +[@earlopain]: https://github.com/earlopain +[@masato-bkn]: https://github.com/masato-bkn pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy