rubocop-rails 2.22.1 → 2.24.1
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 +4 -4
 - data/README.md +7 -9
 - data/config/default.yml +4 -2
 - data/lib/rubocop/cop/mixin/active_record_helper.rb +15 -3
 - data/lib/rubocop/cop/mixin/database_type_resolvable.rb +1 -1
 - data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +2 -0
 - data/lib/rubocop/cop/rails/active_record_aliases.rb +2 -2
 - data/lib/rubocop/cop/rails/active_support_aliases.rb +6 -5
 - data/lib/rubocop/cop/rails/active_support_on_load.rb +21 -1
 - data/lib/rubocop/cop/rails/after_commit_override.rb +1 -1
 - data/lib/rubocop/cop/rails/bulk_change_table.rb +4 -4
 - data/lib/rubocop/cop/rails/content_tag.rb +1 -1
 - data/lib/rubocop/cop/rails/dangerous_column_names.rb +2 -3
 - data/lib/rubocop/cop/rails/eager_evaluation_log_message.rb +2 -2
 - data/lib/rubocop/cop/rails/expanded_date_range.rb +1 -1
 - data/lib/rubocop/cop/rails/file_path.rb +5 -5
 - data/lib/rubocop/cop/rails/find_by.rb +3 -3
 - data/lib/rubocop/cop/rails/find_by_id.rb +9 -23
 - data/lib/rubocop/cop/rails/inquiry.rb +1 -0
 - data/lib/rubocop/cop/rails/inverse_of.rb +1 -1
 - data/lib/rubocop/cop/rails/pick.rb +6 -5
 - data/lib/rubocop/cop/rails/pluck.rb +1 -1
 - data/lib/rubocop/cop/rails/pluck_id.rb +2 -1
 - data/lib/rubocop/cop/rails/pluck_in_where.rb +18 -5
 - data/lib/rubocop/cop/rails/rake_environment.rb +2 -2
 - data/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +42 -30
 - data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -1
 - data/lib/rubocop/cop/rails/response_parsed_body.rb +52 -10
 - data/lib/rubocop/cop/rails/reversible_migration.rb +3 -3
 - data/lib/rubocop/cop/rails/save_bang.rb +6 -4
 - data/lib/rubocop/cop/rails/time_zone.rb +2 -1
 - data/lib/rubocop/cop/rails/uniq_before_pluck.rb +12 -4
 - data/lib/rubocop/cop/rails/unique_validation_without_index.rb +1 -1
 - data/lib/rubocop/cop/rails/unknown_env.rb +3 -3
 - data/lib/rubocop/cop/rails/validation.rb +2 -2
 - data/lib/rubocop/cop/rails/where_equals.rb +3 -2
 - data/lib/rubocop/cop/rails/where_exists.rb +9 -8
 - data/lib/rubocop/cop/rails/where_missing.rb +6 -2
 - data/lib/rubocop/cop/rails/where_not.rb +8 -6
 - data/lib/rubocop/rails/schema_loader/schema.rb +3 -2
 - data/lib/rubocop/rails/schema_loader.rb +5 -15
 - data/lib/rubocop/rails/version.rb +1 -1
 - metadata +24 -4
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: ee7d9bdd0fa7838d8bfecece133ccd92cc308603bcdf120c14224c5f2e312344
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 7d740b495ffa368d26a73808af9adff990bb9c1d317d905f877b4f3e2025487c
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 98172f41e7b1aab55931f351757425815850809edd6fc4f5bc55c59271d9f12459ac51c2002e409534b623f321ab27798c32aaccb2d15d60c7bf309a9c044d58
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c78e9a0d9e53e5203a2dd1846a79c3e9c7a16af69e98d94e6b7ae6358ae6a29b71c2ac3f09ddb2a9be06dc64097a736c3379730f50b9309c0e2ae084267aee70
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -66,17 +66,15 @@ end 
     | 
|
| 
       66 
66 
     | 
    
         
             
            ## Rails configuration tip
         
     | 
| 
       67 
67 
     | 
    
         | 
| 
       68 
68 
     | 
    
         
             
            If you are using Rails 6.1 or newer, add the following `config.generators.after_generate` setting to
         
     | 
| 
       69 
     | 
    
         
            -
            your config/ 
     | 
| 
      
 69 
     | 
    
         
            +
            your `config/environments/development.rb` to apply RuboCop autocorrection to code generated by `bin/rails g`.
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
71 
     | 
    
         
             
            ```ruby
         
     | 
| 
       72 
     | 
    
         
            -
            # config/ 
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
               
     | 
| 
       75 
     | 
    
         
            -
                 
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                   
     | 
| 
       78 
     | 
    
         
            -
                    system("bundle exec rubocop -A --fail-level=E #{parsable_files.shelljoin}", exception: true)
         
     | 
| 
       79 
     | 
    
         
            -
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
            # config/environments/development.rb
         
     | 
| 
      
 73 
     | 
    
         
            +
            Rails.application.configure do
         
     | 
| 
      
 74 
     | 
    
         
            +
              config.generators.after_generate do |files|
         
     | 
| 
      
 75 
     | 
    
         
            +
                parsable_files = files.filter { |file| file.end_with?('.rb') }
         
     | 
| 
      
 76 
     | 
    
         
            +
                unless parsable_files.empty?
         
     | 
| 
      
 77 
     | 
    
         
            +
                  system("bundle exec rubocop -A --fail-level=E #{parsable_files.shelljoin}", exception: true)
         
     | 
| 
       80 
78 
     | 
    
         
             
                end
         
     | 
| 
       81 
79 
     | 
    
         
             
              end
         
     | 
| 
       82 
80 
     | 
    
         
             
            end
         
     | 
    
        data/config/default.yml
    CHANGED
    
    | 
         @@ -165,6 +165,7 @@ Rails/ActiveSupportOnLoad: 
     | 
|
| 
       165 
165 
     | 
    
         
             
                - 'https://guides.rubyonrails.org/engines.html#available-load-hooks'
         
     | 
| 
       166 
166 
     | 
    
         
             
              SafeAutoCorrect: false
         
     | 
| 
       167 
167 
     | 
    
         
             
              VersionAdded: '2.16'
         
     | 
| 
      
 168 
     | 
    
         
            +
              VersionChanged: '2.24'
         
     | 
| 
       168 
169 
     | 
    
         | 
| 
       169 
170 
     | 
    
         
             
            Rails/AddColumnIndex:
         
     | 
| 
       170 
171 
     | 
    
         
             
              Description: >-
         
     | 
| 
         @@ -445,9 +446,10 @@ Rails/EnvironmentVariableAccess: 
     | 
|
| 
       445 
446 
     | 
    
         
             
              # TODO: Set to `pending` status in RuboCop Rails 2 series when migration doc will be written.
         
     | 
| 
       446 
447 
     | 
    
         
             
              Enabled: false
         
     | 
| 
       447 
448 
     | 
    
         
             
              VersionAdded: '2.10'
         
     | 
| 
       448 
     | 
    
         
            -
              VersionChanged: '2. 
     | 
| 
      
 449 
     | 
    
         
            +
              VersionChanged: '2.24'
         
     | 
| 
       449 
450 
     | 
    
         
             
              Include:
         
     | 
| 
       450 
451 
     | 
    
         
             
                - app/**/*.rb
         
     | 
| 
      
 452 
     | 
    
         
            +
                - config/initializers/**/*.rb
         
     | 
| 
       451 
453 
     | 
    
         
             
                - lib/**/*.rb
         
     | 
| 
       452 
454 
     | 
    
         
             
              Exclude:
         
     | 
| 
       453 
455 
     | 
    
         
             
                - lib/**/*.rake
         
     | 
| 
         @@ -902,7 +904,7 @@ Rails/RequireDependency: 
     | 
|
| 
       902 
904 
     | 
    
         
             
              VersionAdded: '2.10'
         
     | 
| 
       903 
905 
     | 
    
         | 
| 
       904 
906 
     | 
    
         
             
            Rails/ResponseParsedBody:
         
     | 
| 
       905 
     | 
    
         
            -
              Description: Prefer `response.parsed_body` to ` 
     | 
| 
      
 907 
     | 
    
         
            +
              Description: Prefer `response.parsed_body` to custom parsing logic for `response.body`.
         
     | 
| 
       906 
908 
     | 
    
         
             
              Enabled: pending
         
     | 
| 
       907 
909 
     | 
    
         
             
              Safe: false
         
     | 
| 
       908 
910 
     | 
    
         
             
              VersionAdded: '2.18'
         
     | 
| 
         @@ -39,7 +39,12 @@ module RuboCop 
     | 
|
| 
       39 
39 
     | 
    
         
             
                  end
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
                  def schema
         
     | 
| 
       42 
     | 
    
         
            -
                    RuboCop 
     | 
| 
      
 42 
     | 
    
         
            +
                    # For compatibility with RuboCop 1.61.0 or lower.
         
     | 
| 
      
 43 
     | 
    
         
            +
                    if respond_to?(:parser_engine)
         
     | 
| 
      
 44 
     | 
    
         
            +
                      RuboCop::Rails::SchemaLoader.load(target_ruby_version, parser_engine)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    else
         
     | 
| 
      
 46 
     | 
    
         
            +
                      RuboCop::Rails::SchemaLoader.load(target_ruby_version, :parser_whitequark)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
       43 
48 
     | 
    
         
             
                  end
         
     | 
| 
       44 
49 
     | 
    
         | 
| 
       45 
50 
     | 
    
         
             
                  def table_name(class_node)
         
     | 
| 
         @@ -98,8 +103,15 @@ module RuboCop 
     | 
|
| 
       98 
103 
     | 
    
         
             
                  end
         
     | 
| 
       99 
104 
     | 
    
         | 
| 
       100 
105 
     | 
    
         
             
                  def in_where?(node)
         
     | 
| 
       101 
     | 
    
         
            -
                    send_node = node.each_ancestor(:send).first
         
     | 
| 
       102 
     | 
    
         
            -
                     
     | 
| 
      
 106 
     | 
    
         
            +
                    send_node = node.each_ancestor(:send, :csend).first
         
     | 
| 
      
 107 
     | 
    
         
            +
                    return false unless send_node
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                    return true if WHERE_METHODS.include?(send_node.method_name)
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                    receiver = send_node.receiver
         
     | 
| 
      
 112 
     | 
    
         
            +
                    return false unless receiver&.send_type?
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    send_node.method?(:not) && WHERE_METHODS.include?(receiver.method_name)
         
     | 
| 
       103 
115 
     | 
    
         
             
                  end
         
     | 
| 
       104 
116 
     | 
    
         
             
                end
         
     | 
| 
       105 
117 
     | 
    
         
             
              end
         
     | 
| 
         @@ -99,6 +99,8 @@ module RuboCop 
     | 
|
| 
       99 
99 
     | 
    
         | 
| 
       100 
100 
     | 
    
         
             
                    def use_redirect_to?(context)
         
     | 
| 
       101 
101 
     | 
    
         
             
                      context.right_siblings.compact.any? do |sibling|
         
     | 
| 
      
 102 
     | 
    
         
            +
                        # Unwrap `return redirect_to :index`
         
     | 
| 
      
 103 
     | 
    
         
            +
                        sibling = sibling.children.first if sibling.return_type? && sibling.children.one?
         
     | 
| 
       102 
104 
     | 
    
         
             
                        sibling.send_type? && sibling.method?(:redirect_to)
         
     | 
| 
       103 
105 
     | 
    
         
             
                      end
         
     | 
| 
       104 
106 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -11,10 +11,10 @@ module RuboCop 
     | 
|
| 
       11 
11 
     | 
    
         
             
                  #   `update` but the method name remained same in the method definition.
         
     | 
| 
       12 
12 
     | 
    
         
             
                  #
         
     | 
| 
       13 
13 
     | 
    
         
             
                  # @example
         
     | 
| 
       14 
     | 
    
         
            -
                  #   #bad
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
       15 
15 
     | 
    
         
             
                  #   book.update_attributes!(author: 'Alice')
         
     | 
| 
       16 
16 
     | 
    
         
             
                  #
         
     | 
| 
       17 
     | 
    
         
            -
                  #   #good
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   # good
         
     | 
| 
       18 
18 
     | 
    
         
             
                  #   book.update!(author: 'Alice')
         
     | 
| 
       19 
19 
     | 
    
         
             
                  class ActiveRecordAliases < Base
         
     | 
| 
       20 
20 
     | 
    
         
             
                    extend AutoCorrector
         
     | 
| 
         @@ -27,13 +27,13 @@ module RuboCop 
     | 
|
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                    ALIASES = {
         
     | 
| 
       29 
29 
     | 
    
         
             
                      starts_with?: {
         
     | 
| 
       30 
     | 
    
         
            -
                        original: :start_with?, matcher: '( 
     | 
| 
      
 30 
     | 
    
         
            +
                        original: :start_with?, matcher: '(call str :starts_with? _)'
         
     | 
| 
       31 
31 
     | 
    
         
             
                      },
         
     | 
| 
       32 
32 
     | 
    
         
             
                      ends_with?: {
         
     | 
| 
       33 
     | 
    
         
            -
                        original: :end_with?, matcher: '( 
     | 
| 
      
 33 
     | 
    
         
            +
                        original: :end_with?, matcher: '(call str :ends_with? _)'
         
     | 
| 
       34 
34 
     | 
    
         
             
                      },
         
     | 
| 
       35 
     | 
    
         
            -
                      append: { original: :<<, matcher: '( 
     | 
| 
       36 
     | 
    
         
            -
                      prepend: { original: :unshift, matcher: '( 
     | 
| 
      
 35 
     | 
    
         
            +
                      append: { original: :<<, matcher: '(call array :append _)' },
         
     | 
| 
      
 36 
     | 
    
         
            +
                      prepend: { original: :unshift, matcher: '(call array :prepend _)' }
         
     | 
| 
       37 
37 
     | 
    
         
             
                    }.freeze
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
                    ALIASES.each do |aliased_method, options|
         
     | 
| 
         @@ -47,13 +47,14 @@ module RuboCop 
     | 
|
| 
       47 
47 
     | 
    
         
             
                        preferred_method = ALIASES[aliased_method][:original]
         
     | 
| 
       48 
48 
     | 
    
         
             
                        message = format(MSG, prefer: preferred_method, current: aliased_method)
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                        add_offense(node, message: message) do |corrector|
         
     | 
| 
      
 50 
     | 
    
         
            +
                        add_offense(node.loc.selector.join(node.source_range.end), message: message) do |corrector|
         
     | 
| 
       51 
51 
     | 
    
         
             
                          next if append(node)
         
     | 
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         
             
                          corrector.replace(node.loc.selector, preferred_method)
         
     | 
| 
       54 
54 
     | 
    
         
             
                        end
         
     | 
| 
       55 
55 
     | 
    
         
             
                      end
         
     | 
| 
       56 
56 
     | 
    
         
             
                    end
         
     | 
| 
      
 57 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       57 
58 
     | 
    
         
             
                  end
         
     | 
| 
       58 
59 
     | 
    
         
             
                end
         
     | 
| 
       59 
60 
     | 
    
         
             
              end
         
     | 
| 
         @@ -55,15 +55,35 @@ module RuboCop 
     | 
|
| 
       55 
55 
     | 
    
         
             
                      'ActiveSupport::TestCase' => 'active_support_test_case'
         
     | 
| 
       56 
56 
     | 
    
         
             
                    }.freeze
         
     | 
| 
       57 
57 
     | 
    
         | 
| 
      
 58 
     | 
    
         
            +
                    RAILS_5_2_LOAD_HOOKS = {
         
     | 
| 
      
 59 
     | 
    
         
            +
                      'ActiveRecord::ConnectionAdapters::SQLite3Adapter' => 'active_record_sqlite3adapter'
         
     | 
| 
      
 60 
     | 
    
         
            +
                    }.freeze
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                    RAILS_7_1_LOAD_HOOKS = {
         
     | 
| 
      
 63 
     | 
    
         
            +
                      'ActiveRecord::TestFixtures' => 'active_record_fixtures',
         
     | 
| 
      
 64 
     | 
    
         
            +
                      'ActiveModel::Model' => 'active_model',
         
     | 
| 
      
 65 
     | 
    
         
            +
                      'ActionText::EncryptedRichText' => 'action_text_encrypted_rich_text',
         
     | 
| 
      
 66 
     | 
    
         
            +
                      'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter' => 'active_record_postgresqladapter',
         
     | 
| 
      
 67 
     | 
    
         
            +
                      'ActiveRecord::ConnectionAdapters::Mysql2Adapter' => 'active_record_mysql2adapter',
         
     | 
| 
      
 68 
     | 
    
         
            +
                      'ActiveRecord::ConnectionAdapters::TrilogyAdapter' => 'active_record_trilogyadapter'
         
     | 
| 
      
 69 
     | 
    
         
            +
                    }.freeze
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
       58 
71 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       59 
72 
     | 
    
         
             
                      receiver, method, arguments = *node # rubocop:disable InternalAffairs/NodeDestructuring
         
     | 
| 
       60 
     | 
    
         
            -
                      return unless  
     | 
| 
      
 73 
     | 
    
         
            +
                      return unless arguments && (hook = hook_for_const(receiver&.const_name))
         
     | 
| 
       61 
74 
     | 
    
         | 
| 
       62 
75 
     | 
    
         
             
                      preferred = "ActiveSupport.on_load(:#{hook}) { #{method} #{arguments.source} }"
         
     | 
| 
       63 
76 
     | 
    
         
             
                      add_offense(node, message: format(MSG, prefer: preferred, current: node.source)) do |corrector|
         
     | 
| 
       64 
77 
     | 
    
         
             
                        corrector.replace(node, preferred)
         
     | 
| 
       65 
78 
     | 
    
         
             
                      end
         
     | 
| 
       66 
79 
     | 
    
         
             
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    def hook_for_const(const_name)
         
     | 
| 
      
 82 
     | 
    
         
            +
                      hook = LOAD_HOOKS[const_name]
         
     | 
| 
      
 83 
     | 
    
         
            +
                      hook ||= RAILS_5_2_LOAD_HOOKS[const_name] if target_rails_version >= 5.2
         
     | 
| 
      
 84 
     | 
    
         
            +
                      hook ||= RAILS_7_1_LOAD_HOOKS[const_name] if target_rails_version >= 7.1
         
     | 
| 
      
 85 
     | 
    
         
            +
                      hook
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
       67 
87 
     | 
    
         
             
                  end
         
     | 
| 
       68 
88 
     | 
    
         
             
                end
         
     | 
| 
       69 
89 
     | 
    
         
             
              end
         
     | 
| 
         @@ -48,7 +48,7 @@ module RuboCop 
     | 
|
| 
       48 
48 
     | 
    
         
             
                      seen_callback_names = {}
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         
             
                      each_after_commit_callback(class_node) do |node|
         
     | 
| 
       51 
     | 
    
         
            -
                        callback_name = node. 
     | 
| 
      
 51 
     | 
    
         
            +
                        callback_name = node.first_argument.value
         
     | 
| 
       52 
52 
     | 
    
         
             
                        if seen_callback_names.key?(callback_name)
         
     | 
| 
       53 
53 
     | 
    
         
             
                          add_offense(node, message: format(MSG, name: callback_name))
         
     | 
| 
       54 
54 
     | 
    
         
             
                        else
         
     | 
| 
         @@ -14,7 +14,7 @@ module RuboCop 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  # automatically detect an adapter from `development` environment
         
     | 
| 
       15 
15 
     | 
    
         
             
                  # in `config/database.yml` or the environment variable `DATABASE_URL`
         
     | 
| 
       16 
16 
     | 
    
         
             
                  # when the `Database` option is not set.
         
     | 
| 
       17 
     | 
    
         
            -
                  # If the adapter is not `mysql2`, `trilogy`, or ` 
     | 
| 
      
 17 
     | 
    
         
            +
                  # If the adapter is not `mysql2`, `trilogy`, `postgresql`, or `postgis`,
         
     | 
| 
       18 
18 
     | 
    
         
             
                  # this Cop ignores offenses.
         
     | 
| 
       19 
19 
     | 
    
         
             
                  #
         
     | 
| 
       20 
20 
     | 
    
         
             
                  # @example
         
     | 
| 
         @@ -212,7 +212,7 @@ module RuboCop 
     | 
|
| 
       212 
212 
     | 
    
         
             
                    # @param node [RuboCop::AST::SendNode]
         
     | 
| 
       213 
213 
     | 
    
         
             
                    def add_offense_for_alter_methods(node)
         
     | 
| 
       214 
214 
     | 
    
         
             
                      # arguments: [{(sym :table)(str "table")} ...]
         
     | 
| 
       215 
     | 
    
         
            -
                      table_node = node. 
     | 
| 
      
 215 
     | 
    
         
            +
                      table_node = node.first_argument
         
     | 
| 
       216 
216 
     | 
    
         
             
                      return unless table_node.is_a? RuboCop::AST::BasicLiteralNode
         
     | 
| 
       217 
217 
     | 
    
         | 
| 
       218 
218 
     | 
    
         
             
                      message = format(MSG_FOR_ALTER_METHODS, table: table_node.value)
         
     | 
| 
         @@ -234,10 +234,10 @@ module RuboCop 
     | 
|
| 
       234 
234 
     | 
    
         
             
                      # @param new_node [RuboCop::AST::SendNode]
         
     | 
| 
       235 
235 
     | 
    
         
             
                      def process(new_node)
         
     | 
| 
       236 
236 
     | 
    
         
             
                        # arguments: [{(sym :table)(str "table")} ...]
         
     | 
| 
       237 
     | 
    
         
            -
                        table_node = new_node. 
     | 
| 
      
 237 
     | 
    
         
            +
                        table_node = new_node.first_argument
         
     | 
| 
       238 
238 
     | 
    
         
             
                        if table_node.is_a? RuboCop::AST::BasicLiteralNode
         
     | 
| 
       239 
239 
     | 
    
         
             
                          flush unless @nodes.all? do |node|
         
     | 
| 
       240 
     | 
    
         
            -
                            node. 
     | 
| 
      
 240 
     | 
    
         
            +
                            node.first_argument.value.to_s == table_node.value.to_s
         
     | 
| 
       241 
241 
     | 
    
         
             
                          end
         
     | 
| 
       242 
242 
     | 
    
         
             
                          @nodes << new_node
         
     | 
| 
       243 
243 
     | 
    
         
             
                        else
         
     | 
| 
         @@ -7,7 +7,7 @@ module RuboCop 
     | 
|
| 
       7 
7 
     | 
    
         
             
                  #
         
     | 
| 
       8 
8 
     | 
    
         
             
                  # NOTE: Allow `tag` when the first argument is a variable because
         
     | 
| 
       9 
9 
     | 
    
         
             
                  # `tag(name)` is simpler rather than `tag.public_send(name)`.
         
     | 
| 
       10 
     | 
    
         
            -
                  # And this cop will be renamed to something like `LegacyTag` in the future. (e.g. RuboCop Rails  
     | 
| 
      
 10 
     | 
    
         
            +
                  # And this cop will be renamed to something like `LegacyTag` in the future. (e.g. RuboCop Rails 3.0)
         
     | 
| 
       11 
11 
     | 
    
         
             
                  #
         
     | 
| 
       12 
12 
     | 
    
         
             
                  # @example
         
     | 
| 
       13 
13 
     | 
    
         
             
                  #  # bad
         
     | 
| 
         @@ -31,7 +31,7 @@ module RuboCop 
     | 
|
| 
       31 
31 
     | 
    
         
             
                      time
         
     | 
| 
       32 
32 
     | 
    
         
             
                    ].to_set.freeze
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                    # Generated from `ActiveRecord::AttributeMethods.dangerous_attribute_methods` on activerecord 7.1. 
     | 
| 
      
 34 
     | 
    
         
            +
                    # Generated from `ActiveRecord::AttributeMethods.dangerous_attribute_methods` on activerecord 7.1.3.
         
     | 
| 
       35 
35 
     | 
    
         
             
                    # rubocop:disable Metrics/CollectionLiteralLength
         
     | 
| 
       36 
36 
     | 
    
         
             
                    DANGEROUS_COLUMN_NAMES = %w[
         
     | 
| 
       37 
37 
     | 
    
         
             
                      __callbacks
         
     | 
| 
         @@ -290,7 +290,6 @@ module RuboCop 
     | 
|
| 
       290 
290 
     | 
    
         
             
                      new_record
         
     | 
| 
       291 
291 
     | 
    
         
             
                      no_touching
         
     | 
| 
       292 
292 
     | 
    
         
             
                      normalize_reflection_attribute
         
     | 
| 
       293 
     | 
    
         
            -
                      object_id
         
     | 
| 
       294 
293 
     | 
    
         
             
                      partial_inserts
         
     | 
| 
       295 
294 
     | 
    
         
             
                      partial_updates
         
     | 
| 
       296 
295 
     | 
    
         
             
                      perform_validations
         
     | 
| 
         @@ -428,7 +427,7 @@ module RuboCop 
     | 
|
| 
       428 
427 
     | 
    
         
             
                      when :rename_column
         
     | 
| 
       429 
428 
     | 
    
         
             
                        node.arguments[2]
         
     | 
| 
       430 
429 
     | 
    
         
             
                      when *COLUMN_TYPE_METHOD_NAMES
         
     | 
| 
       431 
     | 
    
         
            -
                        node. 
     | 
| 
      
 430 
     | 
    
         
            +
                        node.first_argument
         
     | 
| 
       432 
431 
     | 
    
         
             
                      end
         
     | 
| 
       433 
432 
     | 
    
         
             
                    end
         
     | 
| 
       434 
433 
     | 
    
         | 
| 
         @@ -14,10 +14,10 @@ module RuboCop 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  # when no output would be produced anyway.
         
     | 
| 
       15 
15 
     | 
    
         
             
                  #
         
     | 
| 
       16 
16 
     | 
    
         
             
                  # @example
         
     | 
| 
       17 
     | 
    
         
            -
                  #   #bad
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
       18 
18 
     | 
    
         
             
                  #   Rails.logger.debug "The time is #{Time.zone.now}."
         
     | 
| 
       19 
19 
     | 
    
         
             
                  #
         
     | 
| 
       20 
     | 
    
         
            -
                  #   #good
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #   # good
         
     | 
| 
       21 
21 
     | 
    
         
             
                  #   Rails.logger.debug { "The time is #{Time.zone.now}." }
         
     | 
| 
       22 
22 
     | 
    
         
             
                  #
         
     | 
| 
       23 
23 
     | 
    
         
             
                  class EagerEvaluationLogMessage < Base
         
     | 
| 
         @@ -51,7 +51,7 @@ module RuboCop 
     | 
|
| 
       51 
51 
     | 
    
         
             
                      return if allow?(begin_node, end_node)
         
     | 
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         
             
                      preferred_method = preferred_method(begin_node)
         
     | 
| 
       54 
     | 
    
         
            -
                      if begin_node.method?(:beginning_of_week) && begin_node.arguments.one?
         
     | 
| 
      
 54 
     | 
    
         
            +
                      if begin_node.method?(:beginning_of_week) && begin_node.arguments.one? && end_node.arguments.one?
         
     | 
| 
       55 
55 
     | 
    
         
             
                        return unless same_argument?(begin_node, end_node)
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
                        preferred_method << "(#{begin_node.first_argument.source})"
         
     | 
| 
         @@ -163,9 +163,9 @@ module RuboCop 
     | 
|
| 
       163 
163 
     | 
    
         | 
| 
       164 
164 
     | 
    
         
             
                    def autocorrect_extension_after_rails_root_join_in_dstr(corrector, node, rails_root_index, extension_node)
         
     | 
| 
       165 
165 
     | 
    
         
             
                      rails_root_node = node.children[rails_root_index].children.first
         
     | 
| 
       166 
     | 
    
         
            -
                      return unless rails_root_node. 
     | 
| 
      
 166 
     | 
    
         
            +
                      return unless rails_root_node.last_argument.str_type?
         
     | 
| 
       167 
167 
     | 
    
         | 
| 
       168 
     | 
    
         
            -
                      corrector.insert_before(rails_root_node. 
     | 
| 
      
 168 
     | 
    
         
            +
                      corrector.insert_before(rails_root_node.last_argument.location.end, extension_node.source)
         
     | 
| 
       169 
169 
     | 
    
         
             
                      corrector.remove(extension_node)
         
     | 
| 
       170 
170 
     | 
    
         
             
                    end
         
     | 
| 
       171 
171 
     | 
    
         | 
| 
         @@ -174,7 +174,7 @@ module RuboCop 
     | 
|
| 
       174 
174 
     | 
    
         
             
                      corrector.remove(
         
     | 
| 
       175 
175 
     | 
    
         
             
                        range_with_surrounding_space(
         
     | 
| 
       176 
176 
     | 
    
         
             
                          range_with_surrounding_comma(
         
     | 
| 
       177 
     | 
    
         
            -
                            node. 
     | 
| 
      
 177 
     | 
    
         
            +
                            node.first_argument.source_range,
         
     | 
| 
       178 
178 
     | 
    
         
             
                            :right
         
     | 
| 
       179 
179 
     | 
    
         
             
                          ),
         
     | 
| 
       180 
180 
     | 
    
         
             
                          side: :right
         
     | 
| 
         @@ -187,7 +187,7 @@ module RuboCop 
     | 
|
| 
       187 
187 
     | 
    
         
             
                    end
         
     | 
| 
       188 
188 
     | 
    
         | 
| 
       189 
189 
     | 
    
         
             
                    def autocorrect_rails_root_join_with_string_arguments(corrector, node)
         
     | 
| 
       190 
     | 
    
         
            -
                      corrector.replace(node. 
     | 
| 
      
 190 
     | 
    
         
            +
                      corrector.replace(node.first_argument, %("#{node.arguments.map(&:value).join('/')}"))
         
     | 
| 
       191 
191 
     | 
    
         
             
                      node.arguments[1..].each do |argument|
         
     | 
| 
       192 
192 
     | 
    
         
             
                        corrector.remove(
         
     | 
| 
       193 
193 
     | 
    
         
             
                          range_with_surrounding_comma(
         
     | 
| 
         @@ -221,7 +221,7 @@ module RuboCop 
     | 
|
| 
       221 
221 
     | 
    
         
             
                    end
         
     | 
| 
       222 
222 
     | 
    
         | 
| 
       223 
223 
     | 
    
         
             
                    def append_argument(corrector, node, argument_source)
         
     | 
| 
       224 
     | 
    
         
            -
                      corrector.insert_after(node. 
     | 
| 
      
 224 
     | 
    
         
            +
                      corrector.insert_after(node.last_argument, %(, "#{argument_source}"))
         
     | 
| 
       225 
225 
     | 
    
         
             
                    end
         
     | 
| 
       226 
226 
     | 
    
         | 
| 
       227 
227 
     | 
    
         
             
                    def replace_with_rails_root_join(corrector, node, argument_source)
         
     | 
| 
         @@ -28,7 +28,7 @@ module RuboCop 
     | 
|
| 
       28 
28 
     | 
    
         
             
                    include RangeHelp
         
     | 
| 
       29 
29 
     | 
    
         
             
                    extend AutoCorrector
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
                    MSG = 'Use `find_by` instead of `where 
     | 
| 
      
 31 
     | 
    
         
            +
                    MSG = 'Use `find_by` instead of `where%<dot>s%<method>s`.'
         
     | 
| 
       32 
32 
     | 
    
         
             
                    RESTRICT_ON_SEND = %i[first take].freeze
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
         @@ -37,7 +37,7 @@ module RuboCop 
     | 
|
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         
             
                      range = offense_range(node)
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                      add_offense(range, message: format(MSG, method: node.method_name)) do |corrector|
         
     | 
| 
      
 40 
     | 
    
         
            +
                      add_offense(range, message: format(MSG, dot: node.loc.dot.source, method: node.method_name)) do |corrector|
         
     | 
| 
       41 
41 
     | 
    
         
             
                        autocorrect(corrector, node)
         
     | 
| 
       42 
42 
     | 
    
         
             
                      end
         
     | 
| 
       43 
43 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -59,7 +59,7 @@ module RuboCop 
     | 
|
| 
       59 
59 
     | 
    
         
             
                      return if node.method?(:first)
         
     | 
| 
       60 
60 
     | 
    
         | 
| 
       61 
61 
     | 
    
         
             
                      where_loc = node.receiver.loc.selector
         
     | 
| 
       62 
     | 
    
         
            -
                      first_loc = range_between(node. 
     | 
| 
      
 62 
     | 
    
         
            +
                      first_loc = range_between(node.receiver.source_range.end_pos, node.loc.selector.end_pos)
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
       64 
64 
     | 
    
         
             
                      corrector.replace(where_loc, 'find_by')
         
     | 
| 
       65 
65 
     | 
    
         
             
                      corrector.replace(first_loc, '')
         
     | 
| 
         @@ -24,40 +24,39 @@ module RuboCop 
     | 
|
| 
       24 
24 
     | 
    
         
             
                    RESTRICT_ON_SEND = %i[take! find_by_id! find_by!].freeze
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                    def_node_matcher :where_take?, <<~PATTERN
         
     | 
| 
       27 
     | 
    
         
            -
                      ( 
     | 
| 
       28 
     | 
    
         
            -
                        $( 
     | 
| 
      
 27 
     | 
    
         
            +
                      (call
         
     | 
| 
      
 28 
     | 
    
         
            +
                        $(call _ :where
         
     | 
| 
       29 
29 
     | 
    
         
             
                          (hash
         
     | 
| 
       30 
30 
     | 
    
         
             
                            (pair (sym :id) $_))) :take!)
         
     | 
| 
       31 
31 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                    def_node_matcher :find_by?, <<~PATTERN
         
     | 
| 
       34 
34 
     | 
    
         
             
                      {
         
     | 
| 
       35 
     | 
    
         
            -
                        ( 
     | 
| 
       36 
     | 
    
         
            -
                        ( 
     | 
| 
      
 35 
     | 
    
         
            +
                        (call _ :find_by_id! $_)
         
     | 
| 
      
 36 
     | 
    
         
            +
                        (call _ :find_by! (hash (pair (sym :id) $_)))
         
     | 
| 
       37 
37 
     | 
    
         
             
                      }
         
     | 
| 
       38 
38 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       41 
41 
     | 
    
         
             
                      where_take?(node) do |where, id_value|
         
     | 
| 
       42 
42 
     | 
    
         
             
                        range = where_take_offense_range(node, where)
         
     | 
| 
       43 
     | 
    
         
            -
                        bad_method = build_where_take_bad_method(id_value)
         
     | 
| 
       44 
43 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                        register_offense(range, id_value 
     | 
| 
      
 44 
     | 
    
         
            +
                        register_offense(range, id_value)
         
     | 
| 
       46 
45 
     | 
    
         
             
                      end
         
     | 
| 
       47 
46 
     | 
    
         | 
| 
       48 
47 
     | 
    
         
             
                      find_by?(node) do |id_value|
         
     | 
| 
       49 
48 
     | 
    
         
             
                        range = find_by_offense_range(node)
         
     | 
| 
       50 
     | 
    
         
            -
                        bad_method = build_find_by_bad_method(node, id_value)
         
     | 
| 
       51 
49 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                        register_offense(range, id_value 
     | 
| 
      
 50 
     | 
    
         
            +
                        register_offense(range, id_value)
         
     | 
| 
       53 
51 
     | 
    
         
             
                      end
         
     | 
| 
       54 
52 
     | 
    
         
             
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       55 
54 
     | 
    
         | 
| 
       56 
55 
     | 
    
         
             
                    private
         
     | 
| 
       57 
56 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
                    def register_offense(range, id_value 
     | 
| 
      
 57 
     | 
    
         
            +
                    def register_offense(range, id_value)
         
     | 
| 
       59 
58 
     | 
    
         
             
                      good_method = build_good_method(id_value)
         
     | 
| 
       60 
     | 
    
         
            -
                      message = format(MSG, good_method: good_method, bad_method:  
     | 
| 
      
 59 
     | 
    
         
            +
                      message = format(MSG, good_method: good_method, bad_method: range.source)
         
     | 
| 
       61 
60 
     | 
    
         | 
| 
       62 
61 
     | 
    
         
             
                      add_offense(range, message: message) do |corrector|
         
     | 
| 
       63 
62 
     | 
    
         
             
                        corrector.replace(range, good_method)
         
     | 
| 
         @@ -75,19 +74,6 @@ module RuboCop 
     | 
|
| 
       75 
74 
     | 
    
         
             
                    def build_good_method(id_value)
         
     | 
| 
       76 
75 
     | 
    
         
             
                      "find(#{id_value.source})"
         
     | 
| 
       77 
76 
     | 
    
         
             
                    end
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                    def build_where_take_bad_method(id_value)
         
     | 
| 
       80 
     | 
    
         
            -
                      "where(id: #{id_value.source}).take!"
         
     | 
| 
       81 
     | 
    
         
            -
                    end
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                    def build_find_by_bad_method(node, id_value)
         
     | 
| 
       84 
     | 
    
         
            -
                      case node.method_name
         
     | 
| 
       85 
     | 
    
         
            -
                      when :find_by_id!
         
     | 
| 
       86 
     | 
    
         
            -
                        "find_by_id!(#{id_value.source})"
         
     | 
| 
       87 
     | 
    
         
            -
                      when :find_by!
         
     | 
| 
       88 
     | 
    
         
            -
                        "find_by!(id: #{id_value.source})"
         
     | 
| 
       89 
     | 
    
         
            -
                      end
         
     | 
| 
       90 
     | 
    
         
            -
                    end
         
     | 
| 
       91 
77 
     | 
    
         
             
                  end
         
     | 
| 
       92 
78 
     | 
    
         
             
                end
         
     | 
| 
       93 
79 
     | 
    
         
             
              end
         
     | 
| 
         @@ -222,7 +222,7 @@ module RuboCop 
     | 
|
| 
       222 
222 
     | 
    
         | 
| 
       223 
223 
     | 
    
         
             
                    def with_options_arguments(recv, node)
         
     | 
| 
       224 
224 
     | 
    
         
             
                      blocks = node.each_ancestor(:block).select do |block|
         
     | 
| 
       225 
     | 
    
         
            -
                        block.send_node.command?(:with_options) && same_context_in_with_options?(block. 
     | 
| 
      
 225 
     | 
    
         
            +
                        block.send_node.command?(:with_options) && same_context_in_with_options?(block.first_argument, recv)
         
     | 
| 
       226 
226 
     | 
    
         
             
                      end
         
     | 
| 
       227 
227 
     | 
    
         
             
                      blocks.flat_map { |n| n.send_node.arguments }
         
     | 
| 
       228 
228 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -28,13 +28,13 @@ module RuboCop 
     | 
|
| 
       28 
28 
     | 
    
         
             
                    extend AutoCorrector
         
     | 
| 
       29 
29 
     | 
    
         
             
                    extend TargetRailsVersion
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
                    MSG = 'Prefer `pick(%<args>s)` over  
     | 
| 
      
 31 
     | 
    
         
            +
                    MSG = 'Prefer `pick(%<args>s)` over `%<current>s`.'
         
     | 
| 
       32 
32 
     | 
    
         
             
                    RESTRICT_ON_SEND = %i[first].freeze
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
                    minimum_target_rails_version 6.0
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
                    def_node_matcher :pick_candidate?, <<~PATTERN
         
     | 
| 
       37 
     | 
    
         
            -
                      ( 
     | 
| 
      
 37 
     | 
    
         
            +
                      (call (call _ :pluck ...) :first)
         
     | 
| 
       38 
38 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
         @@ -44,7 +44,7 @@ module RuboCop 
     | 
|
| 
       44 
44 
     | 
    
         
             
                        node_selector = node.loc.selector
         
     | 
| 
       45 
45 
     | 
    
         
             
                        range = receiver_selector.join(node_selector)
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
                        add_offense(range, message: message(receiver)) do |corrector|
         
     | 
| 
      
 47 
     | 
    
         
            +
                        add_offense(range, message: message(receiver, range)) do |corrector|
         
     | 
| 
       48 
48 
     | 
    
         
             
                          first_range = receiver.source_range.end.join(node_selector)
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         
             
                          corrector.remove(first_range)
         
     | 
| 
         @@ -52,11 +52,12 @@ module RuboCop 
     | 
|
| 
       52 
52 
     | 
    
         
             
                        end
         
     | 
| 
       53 
53 
     | 
    
         
             
                      end
         
     | 
| 
       54 
54 
     | 
    
         
             
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       55 
56 
     | 
    
         | 
| 
       56 
57 
     | 
    
         
             
                    private
         
     | 
| 
       57 
58 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
                    def message(receiver)
         
     | 
| 
       59 
     | 
    
         
            -
                      format(MSG, args: receiver.arguments.map(&:source).join(', '))
         
     | 
| 
      
 59 
     | 
    
         
            +
                    def message(receiver, current)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      format(MSG, args: receiver.arguments.map(&:source).join(', '), current: current.source)
         
     | 
| 
       60 
61 
     | 
    
         
             
                    end
         
     | 
| 
       61 
62 
     | 
    
         
             
                  end
         
     | 
| 
       62 
63 
     | 
    
         
             
                end
         
     | 
| 
         @@ -38,7 +38,7 @@ module RuboCop 
     | 
|
| 
       38 
38 
     | 
    
         
             
                    minimum_target_rails_version 5.0
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                    def_node_matcher :pluck_candidate?, <<~PATTERN
         
     | 
| 
       41 
     | 
    
         
            -
                      ({block numblock} ( 
     | 
| 
      
 41 
     | 
    
         
            +
                      ({block numblock} (call _ {:map :collect}) $_argument (send lvar :[] $_key))
         
     | 
| 
       42 
42 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         
             
                    def on_block(node)
         
     | 
| 
         @@ -34,7 +34,7 @@ module RuboCop 
     | 
|
| 
       34 
34 
     | 
    
         
             
                    RESTRICT_ON_SEND = %i[pluck].freeze
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
                    def_node_matcher :pluck_id_call?, <<~PATTERN
         
     | 
| 
       37 
     | 
    
         
            -
                      ( 
     | 
| 
      
 37 
     | 
    
         
            +
                      (call _ :pluck {(sym :id) (send nil? :primary_key)})
         
     | 
| 
       38 
38 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
         @@ -47,6 +47,7 @@ module RuboCop 
     | 
|
| 
       47 
47 
     | 
    
         
             
                        corrector.replace(offense_range(node), 'ids')
         
     | 
| 
       48 
48 
     | 
    
         
             
                      end
         
     | 
| 
       49 
49 
     | 
    
         
             
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       50 
51 
     | 
    
         | 
| 
       51 
52 
     | 
    
         
             
                    private
         
     | 
| 
       52 
53 
     | 
    
         | 
| 
         @@ -22,10 +22,13 @@ module RuboCop 
     | 
|
| 
       22 
22 
     | 
    
         
             
                  # @example
         
     | 
| 
       23 
23 
     | 
    
         
             
                  #   # bad
         
     | 
| 
       24 
24 
     | 
    
         
             
                  #   Post.where(user_id: User.active.pluck(:id))
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #   Post.where(user_id: User.active.ids)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #   Post.where.not(user_id: User.active.pluck(:id))
         
     | 
| 
       25 
27 
     | 
    
         
             
                  #
         
     | 
| 
       26 
28 
     | 
    
         
             
                  #   # good
         
     | 
| 
       27 
29 
     | 
    
         
             
                  #   Post.where(user_id: User.active.select(:id))
         
     | 
| 
       28 
30 
     | 
    
         
             
                  #   Post.where(user_id: active_users.select(:id))
         
     | 
| 
      
 31 
     | 
    
         
            +
                  #   Post.where.not(user_id: active_users.select(:id))
         
     | 
| 
       29 
32 
     | 
    
         
             
                  #
         
     | 
| 
       30 
33 
     | 
    
         
             
                  # @example EnforcedStyle: conservative (default)
         
     | 
| 
       31 
34 
     | 
    
         
             
                  #   # good
         
     | 
| 
         @@ -40,8 +43,9 @@ module RuboCop 
     | 
|
| 
       40 
43 
     | 
    
         
             
                    include ConfigurableEnforcedStyle
         
     | 
| 
       41 
44 
     | 
    
         
             
                    extend AutoCorrector
         
     | 
| 
       42 
45 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                     
     | 
| 
       44 
     | 
    
         
            -
                     
     | 
| 
      
 46 
     | 
    
         
            +
                    MSG_SELECT = 'Use `select` instead of `pluck` within `where` query method.'
         
     | 
| 
      
 47 
     | 
    
         
            +
                    MSG_IDS = 'Use `select(:id)` instead of `ids` within `where` query method.'
         
     | 
| 
      
 48 
     | 
    
         
            +
                    RESTRICT_ON_SEND = %i[pluck ids].freeze
         
     | 
| 
       45 
49 
     | 
    
         | 
| 
       46 
50 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       47 
51 
     | 
    
         
             
                      return unless in_where?(node)
         
     | 
| 
         @@ -49,17 +53,26 @@ module RuboCop 
     | 
|
| 
       49 
53 
     | 
    
         | 
| 
       50 
54 
     | 
    
         
             
                      range = node.loc.selector
         
     | 
| 
       51 
55 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                       
     | 
| 
       53 
     | 
    
         
            -
                         
     | 
| 
      
 56 
     | 
    
         
            +
                      if node.method?(:ids)
         
     | 
| 
      
 57 
     | 
    
         
            +
                        replacement = 'select(:id)'
         
     | 
| 
      
 58 
     | 
    
         
            +
                        message = MSG_IDS
         
     | 
| 
      
 59 
     | 
    
         
            +
                      else
         
     | 
| 
      
 60 
     | 
    
         
            +
                        replacement = 'select'
         
     | 
| 
      
 61 
     | 
    
         
            +
                        message = MSG_SELECT
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                      add_offense(range, message: message) do |corrector|
         
     | 
| 
      
 65 
     | 
    
         
            +
                        corrector.replace(range, replacement)
         
     | 
| 
       54 
66 
     | 
    
         
             
                      end
         
     | 
| 
       55 
67 
     | 
    
         
             
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       56 
69 
     | 
    
         | 
| 
       57 
70 
     | 
    
         
             
                    private
         
     | 
| 
       58 
71 
     | 
    
         | 
| 
       59 
72 
     | 
    
         
             
                    def root_receiver(node)
         
     | 
| 
       60 
73 
     | 
    
         
             
                      receiver = node.receiver
         
     | 
| 
       61 
74 
     | 
    
         | 
| 
       62 
     | 
    
         
            -
                      if receiver&. 
     | 
| 
      
 75 
     | 
    
         
            +
                      if receiver&.call_type?
         
     | 
| 
       63 
76 
     | 
    
         
             
                        root_receiver(receiver)
         
     | 
| 
       64 
77 
     | 
    
         
             
                      else
         
     | 
| 
       65 
78 
     | 
    
         
             
                        receiver
         
     | 
| 
         @@ -72,7 +72,7 @@ module RuboCop 
     | 
|
| 
       72 
72 
     | 
    
         
             
                    end
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
       74 
74 
     | 
    
         
             
                    def task_name(node)
         
     | 
| 
       75 
     | 
    
         
            -
                      first_arg = node. 
     | 
| 
      
 75 
     | 
    
         
            +
                      first_arg = node.first_argument
         
     | 
| 
       76 
76 
     | 
    
         
             
                      case first_arg&.type
         
     | 
| 
       77 
77 
     | 
    
         
             
                      when :sym, :str
         
     | 
| 
       78 
78 
     | 
    
         
             
                        first_arg.value.to_sym
         
     | 
| 
         @@ -97,7 +97,7 @@ module RuboCop 
     | 
|
| 
       97 
97 
     | 
    
         
             
                    end
         
     | 
| 
       98 
98 
     | 
    
         | 
| 
       99 
99 
     | 
    
         
             
                    def with_dependencies?(node)
         
     | 
| 
       100 
     | 
    
         
            -
                      first_arg = node. 
     | 
| 
      
 100 
     | 
    
         
            +
                      first_arg = node.first_argument
         
     | 
| 
       101 
101 
     | 
    
         
             
                      return false unless first_arg
         
     | 
| 
       102 
102 
     | 
    
         | 
| 
       103 
103 
     | 
    
         
             
                      if first_arg.hash_type?
         
     | 
| 
         @@ -3,8 +3,43 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module RuboCop
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Cop
         
     | 
| 
       5 
5 
     | 
    
         
             
                module Rails
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # TODO: In the future, please support only RuboCop 1.52+ and use `RuboCop::Cop::AllowedReceivers`:
         
     | 
| 
      
 7 
     | 
    
         
            +
                  #       https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cop/mixin/allowed_receivers.rb
         
     | 
| 
      
 8 
     | 
    
         
            +
                  #       At that time, this duplicated module implementation can be removed.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  module AllowedReceivers
         
     | 
| 
      
 10 
     | 
    
         
            +
                    def allowed_receiver?(receiver)
         
     | 
| 
      
 11 
     | 
    
         
            +
                      receiver_name = receiver_name(receiver)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                      allowed_receivers.include?(receiver_name)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    def receiver_name(receiver)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      return receiver_name(receiver.receiver) if receiver.receiver && !receiver.receiver.const_type?
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      if receiver.send_type?
         
     | 
| 
      
 20 
     | 
    
         
            +
                        if receiver.receiver
         
     | 
| 
      
 21 
     | 
    
         
            +
                          "#{receiver_name(receiver.receiver)}.#{receiver.method_name}"
         
     | 
| 
      
 22 
     | 
    
         
            +
                        else
         
     | 
| 
      
 23 
     | 
    
         
            +
                          receiver.method_name.to_s
         
     | 
| 
      
 24 
     | 
    
         
            +
                        end
         
     | 
| 
      
 25 
     | 
    
         
            +
                      else
         
     | 
| 
      
 26 
     | 
    
         
            +
                        receiver.source
         
     | 
| 
      
 27 
     | 
    
         
            +
                      end
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    def allowed_receivers
         
     | 
| 
      
 31 
     | 
    
         
            +
                      cop_config.fetch('AllowedReceivers', [])
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
       6 
35 
     | 
    
         
             
                  # Detect redundant `all` used as a receiver for Active Record query methods.
         
     | 
| 
       7 
36 
     | 
    
         
             
                  #
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # For the methods `delete_all` and `destroy_all`, this cop will only check cases where the receiver is a model.
         
     | 
| 
      
 38 
     | 
    
         
            +
                  # It will ignore cases where the receiver is an association (e.g., `user.articles.all.delete_all`).
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # This is because omitting `all` from an association changes the methods
         
     | 
| 
      
 40 
     | 
    
         
            +
                  # from `ActiveRecord::Relation` to `ActiveRecord::Associations::CollectionProxy`,
         
     | 
| 
      
 41 
     | 
    
         
            +
                  # which can affect their behavior.
         
     | 
| 
      
 42 
     | 
    
         
            +
                  #
         
     | 
| 
       8 
43 
     | 
    
         
             
                  # @safety
         
     | 
| 
       9 
44 
     | 
    
         
             
                  #   This cop is unsafe for autocorrection if the receiver for `all` is not an Active Record object.
         
     | 
| 
       10 
45 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -144,13 +179,15 @@ module RuboCop 
     | 
|
| 
       144 
179 
     | 
    
         
             
                    ].to_set.freeze
         
     | 
| 
       145 
180 
     | 
    
         | 
| 
       146 
181 
     | 
    
         
             
                    POSSIBLE_ENUMERABLE_BLOCK_METHODS = %i[any? count find none? one? select sum].freeze
         
     | 
| 
      
 182 
     | 
    
         
            +
                    SENSITIVE_METHODS_ON_ASSOCIATION = %i[delete_all destroy_all].freeze
         
     | 
| 
       147 
183 
     | 
    
         | 
| 
       148 
184 
     | 
    
         
             
                    def_node_matcher :followed_by_query_method?, <<~PATTERN
         
     | 
| 
       149 
185 
     | 
    
         
             
                      (send (send _ :all) QUERYING_METHODS ...)
         
     | 
| 
       150 
186 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       151 
187 
     | 
    
         | 
| 
       152 
188 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       153 
     | 
    
         
            -
                      return  
     | 
| 
      
 189 
     | 
    
         
            +
                      return unless followed_by_query_method?(node.parent)
         
     | 
| 
      
 190 
     | 
    
         
            +
                      return if possible_enumerable_block_method?(node) || sensitive_association_method?(node)
         
     | 
| 
       154 
191 
     | 
    
         
             
                      return if node.receiver ? allowed_receiver?(node.receiver) : !inherit_active_record_base?(node)
         
     | 
| 
       155 
192 
     | 
    
         | 
| 
       156 
193 
     | 
    
         
             
                      range_of_all_method = offense_range(node)
         
     | 
| 
         @@ -169,37 +206,12 @@ module RuboCop 
     | 
|
| 
       169 
206 
     | 
    
         
             
                      parent.parent&.block_type? || parent.parent&.numblock_type? || parent.first_argument&.block_pass_type?
         
     | 
| 
       170 
207 
     | 
    
         
             
                    end
         
     | 
| 
       171 
208 
     | 
    
         | 
| 
       172 
     | 
    
         
            -
                    def  
     | 
| 
       173 
     | 
    
         
            -
                       
     | 
| 
      
 209 
     | 
    
         
            +
                    def sensitive_association_method?(node)
         
     | 
| 
      
 210 
     | 
    
         
            +
                      !node.receiver&.const_type? && SENSITIVE_METHODS_ON_ASSOCIATION.include?(node.parent.method_name)
         
     | 
| 
       174 
211 
     | 
    
         
             
                    end
         
     | 
| 
       175 
212 
     | 
    
         | 
| 
       176 
     | 
    
         
            -
                     
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
                    #       At that time, this duplicated module implementation can be removed.
         
     | 
| 
       179 
     | 
    
         
            -
                    module AllowedReceivers
         
     | 
| 
       180 
     | 
    
         
            -
                      def allowed_receiver?(receiver)
         
     | 
| 
       181 
     | 
    
         
            -
                        receiver_name = receiver_name(receiver)
         
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
                        allowed_receivers.include?(receiver_name)
         
     | 
| 
       184 
     | 
    
         
            -
                      end
         
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
                      def receiver_name(receiver)
         
     | 
| 
       187 
     | 
    
         
            -
                        return receiver_name(receiver.receiver) if receiver.receiver && !receiver.receiver.const_type?
         
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
                        if receiver.send_type?
         
     | 
| 
       190 
     | 
    
         
            -
                          if receiver.receiver
         
     | 
| 
       191 
     | 
    
         
            -
                            "#{receiver_name(receiver.receiver)}.#{receiver.method_name}"
         
     | 
| 
       192 
     | 
    
         
            -
                          else
         
     | 
| 
       193 
     | 
    
         
            -
                            receiver.method_name.to_s
         
     | 
| 
       194 
     | 
    
         
            -
                          end
         
     | 
| 
       195 
     | 
    
         
            -
                        else
         
     | 
| 
       196 
     | 
    
         
            -
                          receiver.source
         
     | 
| 
       197 
     | 
    
         
            -
                        end
         
     | 
| 
       198 
     | 
    
         
            -
                      end
         
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
                      def allowed_receivers
         
     | 
| 
       201 
     | 
    
         
            -
                        cop_config.fetch('AllowedReceivers', [])
         
     | 
| 
       202 
     | 
    
         
            -
                      end
         
     | 
| 
      
 213 
     | 
    
         
            +
                    def offense_range(node)
         
     | 
| 
      
 214 
     | 
    
         
            +
                      range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
         
     | 
| 
       203 
215 
     | 
    
         
             
                    end
         
     | 
| 
       204 
216 
     | 
    
         
             
                  end
         
     | 
| 
       205 
217 
     | 
    
         
             
                end
         
     | 
| 
         @@ -3,25 +3,30 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module RuboCop
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Cop
         
     | 
| 
       5 
5 
     | 
    
         
             
                module Rails
         
     | 
| 
       6 
     | 
    
         
            -
                  # Prefer `response.parsed_body` to ` 
     | 
| 
      
 6 
     | 
    
         
            +
                  # Prefer `response.parsed_body` to custom parsing logic for `response.body`.
         
     | 
| 
       7 
7 
     | 
    
         
             
                  #
         
     | 
| 
       8 
8 
     | 
    
         
             
                  # @safety
         
     | 
| 
       9 
     | 
    
         
            -
                  #   This cop is unsafe because Content-Type may not be `application/json 
     | 
| 
       10 
     | 
    
         
            -
                  #   Content-Type provided by corporate entities such as 
     | 
| 
       11 
     | 
    
         
            -
                  #   ` 
     | 
| 
      
 9 
     | 
    
         
            +
                  #   This cop is unsafe because Content-Type may not be `application/json` or `text/html`.
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #   For example, the proprietary Content-Type provided by corporate entities such as
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #   `application/vnd.github+json` is not supported at `response.parsed_body` by default,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   so you still have to use `JSON.parse(response.body)` there.
         
     | 
| 
       12 
13 
     | 
    
         
             
                  #
         
     | 
| 
       13 
14 
     | 
    
         
             
                  # @example
         
     | 
| 
       14 
15 
     | 
    
         
             
                  #   # bad
         
     | 
| 
       15 
16 
     | 
    
         
             
                  #   JSON.parse(response.body)
         
     | 
| 
       16 
17 
     | 
    
         
             
                  #
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #   Nokogiri::HTML.parse(response.body)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #   Nokogiri::HTML5.parse(response.body)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #
         
     | 
| 
       17 
24 
     | 
    
         
             
                  #   # good
         
     | 
| 
       18 
25 
     | 
    
         
             
                  #   response.parsed_body
         
     | 
| 
       19 
26 
     | 
    
         
             
                  class ResponseParsedBody < Base
         
     | 
| 
       20 
27 
     | 
    
         
             
                    extend AutoCorrector
         
     | 
| 
       21 
28 
     | 
    
         
             
                    extend TargetRailsVersion
         
     | 
| 
       22 
29 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
                    MSG = 'Prefer `response.parsed_body` to `JSON.parse(response.body)`.'
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
30 
     | 
    
         
             
                    RESTRICT_ON_SEND = %i[parse].freeze
         
     | 
| 
       26 
31 
     | 
    
         | 
| 
       27 
32 
     | 
    
         
             
                    minimum_target_rails_version 5.0
         
     | 
| 
         @@ -38,12 +43,27 @@ module RuboCop 
     | 
|
| 
       38 
43 
     | 
    
         
             
                      )
         
     | 
| 
       39 
44 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       40 
45 
     | 
    
         | 
| 
      
 46 
     | 
    
         
            +
                    # @!method nokogiri_html_parse_response_body(node)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    def_node_matcher :nokogiri_html_parse_response_body, <<~PATTERN
         
     | 
| 
      
 48 
     | 
    
         
            +
                      (send
         
     | 
| 
      
 49 
     | 
    
         
            +
                        (const
         
     | 
| 
      
 50 
     | 
    
         
            +
                          (const {nil? cbase} :Nokogiri)
         
     | 
| 
      
 51 
     | 
    
         
            +
                          ${:HTML :HTML5}
         
     | 
| 
      
 52 
     | 
    
         
            +
                        )
         
     | 
| 
      
 53 
     | 
    
         
            +
                        :parse
         
     | 
| 
      
 54 
     | 
    
         
            +
                        (send
         
     | 
| 
      
 55 
     | 
    
         
            +
                          (send nil? :response)
         
     | 
| 
      
 56 
     | 
    
         
            +
                          :body
         
     | 
| 
      
 57 
     | 
    
         
            +
                        )
         
     | 
| 
      
 58 
     | 
    
         
            +
                      )
         
     | 
| 
      
 59 
     | 
    
         
            +
                    PATTERN
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
       41 
61 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       42 
     | 
    
         
            -
                       
     | 
| 
      
 62 
     | 
    
         
            +
                      check_json_parse_response_body(node)
         
     | 
| 
       43 
63 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                       
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                       
     | 
| 
      
 64 
     | 
    
         
            +
                      return unless target_rails_version >= 7.1
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                      check_nokogiri_html_parse_response_body(node)
         
     | 
| 
       47 
67 
     | 
    
         
             
                    end
         
     | 
| 
       48 
68 
     | 
    
         | 
| 
       49 
69 
     | 
    
         
             
                    private
         
     | 
| 
         @@ -51,6 +71,28 @@ module RuboCop 
     | 
|
| 
       51 
71 
     | 
    
         
             
                    def autocorrect(corrector, node)
         
     | 
| 
       52 
72 
     | 
    
         
             
                      corrector.replace(node, 'response.parsed_body')
         
     | 
| 
       53 
73 
     | 
    
         
             
                    end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                    def check_json_parse_response_body(node)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      return unless json_parse_response_body?(node)
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                      add_offense(
         
     | 
| 
      
 79 
     | 
    
         
            +
                        node,
         
     | 
| 
      
 80 
     | 
    
         
            +
                        message: 'Prefer `response.parsed_body` to `JSON.parse(response.body)`.'
         
     | 
| 
      
 81 
     | 
    
         
            +
                      ) do |corrector|
         
     | 
| 
      
 82 
     | 
    
         
            +
                        autocorrect(corrector, node)
         
     | 
| 
      
 83 
     | 
    
         
            +
                      end
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                    def check_nokogiri_html_parse_response_body(node)
         
     | 
| 
      
 87 
     | 
    
         
            +
                      return unless (const = nokogiri_html_parse_response_body(node))
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                      add_offense(
         
     | 
| 
      
 90 
     | 
    
         
            +
                        node,
         
     | 
| 
      
 91 
     | 
    
         
            +
                        message: "Prefer `response.parsed_body` to `Nokogiri::#{const}.parse(response.body)`."
         
     | 
| 
      
 92 
     | 
    
         
            +
                      ) do |corrector|
         
     | 
| 
      
 93 
     | 
    
         
            +
                        autocorrect(corrector, node)
         
     | 
| 
      
 94 
     | 
    
         
            +
                      end
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
       54 
96 
     | 
    
         
             
                  end
         
     | 
| 
       55 
97 
     | 
    
         
             
                end
         
     | 
| 
       56 
98 
     | 
    
         
             
              end
         
     | 
| 
         @@ -17,7 +17,7 @@ module RuboCop 
     | 
|
| 
       17 
17 
     | 
    
         
             
                  #   # good
         
     | 
| 
       18 
18 
     | 
    
         
             
                  #   def change
         
     | 
| 
       19 
19 
     | 
    
         
             
                  #     change_table :users do |t|
         
     | 
| 
       20 
     | 
    
         
            -
                  #       t.remove :name, :string
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #       t.remove :name, type: :string
         
     | 
| 
       21 
21 
     | 
    
         
             
                  #     end
         
     | 
| 
       22 
22 
     | 
    
         
             
                  #   end
         
     | 
| 
       23 
23 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -290,10 +290,10 @@ module RuboCop 
     | 
|
| 
       290 
290 
     | 
    
         
             
                      when :change
         
     | 
| 
       291 
291 
     | 
    
         
             
                        false
         
     | 
| 
       292 
292 
     | 
    
         
             
                      when :remove
         
     | 
| 
       293 
     | 
    
         
            -
                        target_rails_version >= 6.1 && all_hash_key?(node. 
     | 
| 
      
 293 
     | 
    
         
            +
                        target_rails_version >= 6.1 && all_hash_key?(node.last_argument, :type)
         
     | 
| 
       294 
294 
     | 
    
         
             
                      when :change_default, :change_column_default, :change_table_comment,
         
     | 
| 
       295 
295 
     | 
    
         
             
                           :change_column_comment
         
     | 
| 
       296 
     | 
    
         
            -
                        all_hash_key?(node. 
     | 
| 
      
 296 
     | 
    
         
            +
                        all_hash_key?(node.last_argument, :from, :to)
         
     | 
| 
       297 
297 
     | 
    
         
             
                      else
         
     | 
| 
       298 
298 
     | 
    
         
             
                        true
         
     | 
| 
       299 
299 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -196,6 +196,8 @@ module RuboCop 
     | 
|
| 
       196 
196 
     | 
    
         
             
                    end
         
     | 
| 
       197 
197 
     | 
    
         | 
| 
       198 
198 
     | 
    
         
             
                    def call_to_persisted?(node)
         
     | 
| 
      
 199 
     | 
    
         
            +
                      node = node.parent.condition if node.parenthesized_call? && node.parent.if_type?
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
       199 
201 
     | 
    
         
             
                      node.send_type? && node.method?(:persisted?)
         
     | 
| 
       200 
202 
     | 
    
         
             
                    end
         
     | 
| 
       201 
203 
     | 
    
         | 
| 
         @@ -336,10 +338,10 @@ module RuboCop 
     | 
|
| 
       336 
338 
     | 
    
         | 
| 
       337 
339 
     | 
    
         
             
                    # Check argument signature as no arguments or one hash
         
     | 
| 
       338 
340 
     | 
    
         
             
                    def expected_signature?(node)
         
     | 
| 
       339 
     | 
    
         
            -
                       
     | 
| 
       340 
     | 
    
         
            -
             
     | 
| 
       341 
     | 
    
         
            -
             
     | 
| 
       342 
     | 
    
         
            -
             
     | 
| 
      
 341 
     | 
    
         
            +
                      return true unless node.arguments?
         
     | 
| 
      
 342 
     | 
    
         
            +
                      return false if !node.arguments.one? || node.method?(:destroy)
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
                      node.first_argument.hash_type? || !node.first_argument.literal?
         
     | 
| 
       343 
345 
     | 
    
         
             
                    end
         
     | 
| 
       344 
346 
     | 
    
         
             
                  end
         
     | 
| 
       345 
347 
     | 
    
         
             
                end
         
     | 
| 
         @@ -69,9 +69,10 @@ module RuboCop 
     | 
|
| 
       69 
69 
     | 
    
         
             
                      return if !node.receiver&.str_type? || !node.method?(:to_time)
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
71 
     | 
    
         
             
                      add_offense(node.loc.selector, message: MSG_STRING_TO_TIME) do |corrector|
         
     | 
| 
       72 
     | 
    
         
            -
                        corrector.replace(node, "Time.zone.parse(#{node.receiver.source})")
         
     | 
| 
      
 72 
     | 
    
         
            +
                        corrector.replace(node, "Time.zone.parse(#{node.receiver.source})") unless node.csend_type?
         
     | 
| 
       73 
73 
     | 
    
         
             
                      end
         
     | 
| 
       74 
74 
     | 
    
         
             
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       75 
76 
     | 
    
         | 
| 
       76 
77 
     | 
    
         
             
                    private
         
     | 
| 
       77 
78 
     | 
    
         | 
| 
         @@ -68,15 +68,23 @@ module RuboCop 
     | 
|
| 
       68 
68 
     | 
    
         
             
                      return unless uniq
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
       70 
70 
     | 
    
         
             
                      add_offense(node.loc.selector) do |corrector|
         
     | 
| 
       71 
     | 
    
         
            -
                         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                        corrector.remove(dot_method_with_whitespace(method, node))
         
     | 
| 
       74 
     | 
    
         
            -
                        corrector.insert_before(node.receiver.loc.dot.begin, '.distinct')
         
     | 
| 
      
 71 
     | 
    
         
            +
                        autocorrect(corrector, node)
         
     | 
| 
       75 
72 
     | 
    
         
             
                      end
         
     | 
| 
       76 
73 
     | 
    
         
             
                    end
         
     | 
| 
       77 
74 
     | 
    
         | 
| 
       78 
75 
     | 
    
         
             
                    private
         
     | 
| 
       79 
76 
     | 
    
         | 
| 
      
 77 
     | 
    
         
            +
                    def autocorrect(corrector, node)
         
     | 
| 
      
 78 
     | 
    
         
            +
                      method = node.method_name
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                      corrector.remove(dot_method_with_whitespace(method, node))
         
     | 
| 
      
 81 
     | 
    
         
            +
                      if (dot = node.receiver.loc.dot)
         
     | 
| 
      
 82 
     | 
    
         
            +
                        corrector.insert_before(dot.begin, '.distinct')
         
     | 
| 
      
 83 
     | 
    
         
            +
                      else
         
     | 
| 
      
 84 
     | 
    
         
            +
                        corrector.insert_before(node.receiver, 'distinct.')
         
     | 
| 
      
 85 
     | 
    
         
            +
                      end
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
       80 
88 
     | 
    
         
             
                    def dot_method_with_whitespace(method, node)
         
     | 
| 
       81 
89 
     | 
    
         
             
                      range_between(dot_method_begin_pos(method, node), node.loc.selector.end_pos)
         
     | 
| 
       82 
90 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -87,9 +87,9 @@ module RuboCop 
     | 
|
| 
       87 
87 
     | 
    
         | 
| 
       88 
88 
     | 
    
         
             
                    def environments
         
     | 
| 
       89 
89 
     | 
    
         
             
                      @environments ||= begin
         
     | 
| 
       90 
     | 
    
         
            -
                         
     | 
| 
       91 
     | 
    
         
            -
                         
     | 
| 
       92 
     | 
    
         
            -
                         
     | 
| 
      
 90 
     | 
    
         
            +
                        environments = cop_config['Environments'] || []
         
     | 
| 
      
 91 
     | 
    
         
            +
                        environments << 'local' if target_rails_version >= 7.1
         
     | 
| 
      
 92 
     | 
    
         
            +
                        environments
         
     | 
| 
       93 
93 
     | 
    
         
             
                      end
         
     | 
| 
       94 
94 
     | 
    
         
             
                    end
         
     | 
| 
       95 
95 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -51,7 +51,7 @@ module RuboCop 
     | 
|
| 
       51 
51 
     | 
    
         
             
                      uniqueness
         
     | 
| 
       52 
52 
     | 
    
         
             
                    ].freeze
         
     | 
| 
       53 
53 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
                    RESTRICT_ON_SEND = TYPES.map { |p| "validates_#{p}_of" 
     | 
| 
      
 54 
     | 
    
         
            +
                    RESTRICT_ON_SEND = TYPES.map { |p| :"validates_#{p}_of" }.freeze
         
     | 
| 
       55 
55 
     | 
    
         
             
                    ALLOWLIST = TYPES.map { |p| "validates :column, #{p}: value" }.freeze
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
         @@ -60,7 +60,7 @@ module RuboCop 
     | 
|
| 
       60 
60 
     | 
    
         
             
                      range = node.loc.selector
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
       62 
62 
     | 
    
         
             
                      add_offense(range, message: message(node)) do |corrector|
         
     | 
| 
       63 
     | 
    
         
            -
                        last_argument = node. 
     | 
| 
      
 63 
     | 
    
         
            +
                        last_argument = node.last_argument
         
     | 
| 
       64 
64 
     | 
    
         
             
                        return if !last_argument.literal? && !last_argument.splat_type? && !frozen_array_argument?(last_argument)
         
     | 
| 
       65 
65 
     | 
    
         | 
| 
       66 
66 
     | 
    
         
             
                        corrector.replace(range, 'validates')
         
     | 
| 
         @@ -33,8 +33,8 @@ module RuboCop 
     | 
|
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
                    def_node_matcher :where_method_call?, <<~PATTERN
         
     | 
| 
       35 
35 
     | 
    
         
             
                      {
         
     | 
| 
       36 
     | 
    
         
            -
                        ( 
     | 
| 
       37 
     | 
    
         
            -
                        ( 
     | 
| 
      
 36 
     | 
    
         
            +
                        (call _ :where (array $str_type? $_ ?))
         
     | 
| 
      
 37 
     | 
    
         
            +
                        (call _ :where $str_type? $_ ?)
         
     | 
| 
       38 
38 
     | 
    
         
             
                      }
         
     | 
| 
       39 
39 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
         @@ -55,6 +55,7 @@ module RuboCop 
     | 
|
| 
       55 
55 
     | 
    
         
             
                        end
         
     | 
| 
       56 
56 
     | 
    
         
             
                      end
         
     | 
| 
       57 
57 
     | 
    
         
             
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       58 
59 
     | 
    
         | 
| 
       59 
60 
     | 
    
         
             
                    EQ_ANONYMOUS_RE = /\A([\w.]+)\s+=\s+\?\z/.freeze             # column = ?
         
     | 
| 
       60 
61 
     | 
    
         
             
                    IN_ANONYMOUS_RE = /\A([\w.]+)\s+IN\s+\(\?\)\z/i.freeze       # column IN (?)
         
     | 
| 
         @@ -55,11 +55,11 @@ module RuboCop 
     | 
|
| 
       55 
55 
     | 
    
         
             
                    RESTRICT_ON_SEND = %i[exists?].freeze
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
                    def_node_matcher :where_exists_call?, <<~PATTERN
         
     | 
| 
       58 
     | 
    
         
            -
                      ( 
     | 
| 
      
 58 
     | 
    
         
            +
                      (call (call _ :where $...) :exists?)
         
     | 
| 
       59 
59 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       60 
60 
     | 
    
         | 
| 
       61 
61 
     | 
    
         
             
                    def_node_matcher :exists_with_args?, <<~PATTERN
         
     | 
| 
       62 
     | 
    
         
            -
                      ( 
     | 
| 
      
 62 
     | 
    
         
            +
                      (call _ :exists? $...)
         
     | 
| 
       63 
63 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
         @@ -67,7 +67,7 @@ module RuboCop 
     | 
|
| 
       67 
67 
     | 
    
         
             
                        return unless convertable_args?(args)
         
     | 
| 
       68 
68 
     | 
    
         | 
| 
       69 
69 
     | 
    
         
             
                        range = correction_range(node)
         
     | 
| 
       70 
     | 
    
         
            -
                        good_method = build_good_method(args)
         
     | 
| 
      
 70 
     | 
    
         
            +
                        good_method = build_good_method(args, dot: node.loc.dot)
         
     | 
| 
       71 
71 
     | 
    
         
             
                        message = format(MSG, good_method: good_method, bad_method: range.source)
         
     | 
| 
       72 
72 
     | 
    
         | 
| 
       73 
73 
     | 
    
         
             
                        add_offense(range, message: message) do |corrector|
         
     | 
| 
         @@ -75,6 +75,7 @@ module RuboCop 
     | 
|
| 
       75 
75 
     | 
    
         
             
                        end
         
     | 
| 
       76 
76 
     | 
    
         
             
                      end
         
     | 
| 
       77 
77 
     | 
    
         
             
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       78 
79 
     | 
    
         | 
| 
       79 
80 
     | 
    
         
             
                    private
         
     | 
| 
       80 
81 
     | 
    
         | 
| 
         @@ -108,11 +109,11 @@ module RuboCop 
     | 
|
| 
       108 
109 
     | 
    
         
             
                      end
         
     | 
| 
       109 
110 
     | 
    
         
             
                    end
         
     | 
| 
       110 
111 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
                    def build_good_method(args)
         
     | 
| 
      
 112 
     | 
    
         
            +
                    def build_good_method(args, dot:)
         
     | 
| 
       112 
113 
     | 
    
         
             
                      if exists_style?
         
     | 
| 
       113 
114 
     | 
    
         
             
                        build_good_method_exists(args)
         
     | 
| 
       114 
115 
     | 
    
         
             
                      elsif where_style?
         
     | 
| 
       115 
     | 
    
         
            -
                        build_good_method_where(args)
         
     | 
| 
      
 116 
     | 
    
         
            +
                        build_good_method_where(args, dot&.source || '.')
         
     | 
| 
       116 
117 
     | 
    
         
             
                      end
         
     | 
| 
       117 
118 
     | 
    
         
             
                    end
         
     | 
| 
       118 
119 
     | 
    
         | 
| 
         @@ -124,11 +125,11 @@ module RuboCop 
     | 
|
| 
       124 
125 
     | 
    
         
             
                      end
         
     | 
| 
       125 
126 
     | 
    
         
             
                    end
         
     | 
| 
       126 
127 
     | 
    
         | 
| 
       127 
     | 
    
         
            -
                    def build_good_method_where(args)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    def build_good_method_where(args, dot_source)
         
     | 
| 
       128 
129 
     | 
    
         
             
                      if args.size > 1
         
     | 
| 
       129 
     | 
    
         
            -
                        "where(#{args.map(&:source).join(', ')}) 
     | 
| 
      
 130 
     | 
    
         
            +
                        "where(#{args.map(&:source).join(', ')})#{dot_source}exists?"
         
     | 
| 
       130 
131 
     | 
    
         
             
                      else
         
     | 
| 
       131 
     | 
    
         
            -
                        "where(#{args[0].source}) 
     | 
| 
      
 132 
     | 
    
         
            +
                        "where(#{args[0].source})#{dot_source}exists?"
         
     | 
| 
       132 
133 
     | 
    
         
             
                      end
         
     | 
| 
       133 
134 
     | 
    
         
             
                    end
         
     | 
| 
       134 
135 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -36,7 +36,7 @@ module RuboCop 
     | 
|
| 
       36 
36 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       39 
     | 
    
         
            -
                      return unless node.first_argument 
     | 
| 
      
 39 
     | 
    
         
            +
                      return unless node.first_argument&.sym_type?
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
                      root_receiver = root_receiver(node)
         
     | 
| 
       42 
42 
     | 
    
         
             
                      where_node_and_argument(root_receiver) do |where_node, where_argument|
         
     | 
| 
         @@ -89,16 +89,20 @@ module RuboCop 
     | 
|
| 
       89 
89 
     | 
    
         
             
                      end
         
     | 
| 
       90 
90 
     | 
    
         
             
                    end
         
     | 
| 
       91 
91 
     | 
    
         | 
| 
      
 92 
     | 
    
         
            +
                    # rubocop:disable Metrics/AbcSize
         
     | 
| 
       92 
93 
     | 
    
         
             
                    def remove_where_method(corrector, node, where_node)
         
     | 
| 
       93 
94 
     | 
    
         
             
                      range = range_between(where_node.loc.selector.begin_pos, where_node.loc.end.end_pos)
         
     | 
| 
       94 
95 
     | 
    
         
             
                      if node.multiline? && !same_line?(node, where_node)
         
     | 
| 
       95 
96 
     | 
    
         
             
                        range = range_by_whole_lines(range, include_final_newline: true)
         
     | 
| 
       96 
     | 
    
         
            -
                       
     | 
| 
      
 97 
     | 
    
         
            +
                      elsif where_node.receiver
         
     | 
| 
       97 
98 
     | 
    
         
             
                        corrector.remove(where_node.loc.dot)
         
     | 
| 
      
 99 
     | 
    
         
            +
                      else
         
     | 
| 
      
 100 
     | 
    
         
            +
                        corrector.remove(node.loc.dot)
         
     | 
| 
       98 
101 
     | 
    
         
             
                      end
         
     | 
| 
       99 
102 
     | 
    
         | 
| 
       100 
103 
     | 
    
         
             
                      corrector.remove(range)
         
     | 
| 
       101 
104 
     | 
    
         
             
                    end
         
     | 
| 
      
 105 
     | 
    
         
            +
                    # rubocop:enable Metrics/AbcSize
         
     | 
| 
       102 
106 
     | 
    
         | 
| 
       103 
107 
     | 
    
         
             
                    def same_line?(left_joins_node, where_node)
         
     | 
| 
       104 
108 
     | 
    
         
             
                      left_joins_node.loc.selector.line == where_node.loc.selector.line
         
     | 
| 
         @@ -32,8 +32,8 @@ module RuboCop 
     | 
|
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                    def_node_matcher :where_method_call?, <<~PATTERN
         
     | 
| 
       34 
34 
     | 
    
         
             
                      {
         
     | 
| 
       35 
     | 
    
         
            -
                        ( 
     | 
| 
       36 
     | 
    
         
            -
                        ( 
     | 
| 
      
 35 
     | 
    
         
            +
                        (call _ :where (array $str_type? $_ ?))
         
     | 
| 
      
 36 
     | 
    
         
            +
                        (call _ :where $str_type? $_ ?)
         
     | 
| 
       37 
37 
     | 
    
         
             
                      }
         
     | 
| 
       38 
38 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
         @@ -46,7 +46,7 @@ module RuboCop 
     | 
|
| 
       46 
46 
     | 
    
         
             
                        column_and_value = extract_column_and_value(template_node, value_node)
         
     | 
| 
       47 
47 
     | 
    
         
             
                        return unless column_and_value
         
     | 
| 
       48 
48 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                        good_method = build_good_method(*column_and_value)
         
     | 
| 
      
 49 
     | 
    
         
            +
                        good_method = build_good_method(node.loc.dot&.source, *column_and_value)
         
     | 
| 
       50 
50 
     | 
    
         
             
                        message = format(MSG, good_method: good_method)
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
       52 
52 
     | 
    
         
             
                        add_offense(range, message: message) do |corrector|
         
     | 
| 
         @@ -54,6 +54,7 @@ module RuboCop 
     | 
|
| 
       54 
54 
     | 
    
         
             
                        end
         
     | 
| 
       55 
55 
     | 
    
         
             
                      end
         
     | 
| 
       56 
56 
     | 
    
         
             
                    end
         
     | 
| 
      
 57 
     | 
    
         
            +
                    alias on_csend on_send
         
     | 
| 
       57 
58 
     | 
    
         | 
| 
       58 
59 
     | 
    
         
             
                    NOT_EQ_ANONYMOUS_RE = /\A([\w.]+)\s+(?:!=|<>)\s+\?\z/.freeze           # column != ?, column <> ?
         
     | 
| 
       59 
60 
     | 
    
         
             
                    NOT_IN_ANONYMOUS_RE = /\A([\w.]+)\s+NOT\s+IN\s+\(\?\)\z/i.freeze       # column NOT IN (?)
         
     | 
| 
         @@ -86,13 +87,14 @@ module RuboCop 
     | 
|
| 
       86 
87 
     | 
    
         
             
                      [Regexp.last_match(1), value]
         
     | 
| 
       87 
88 
     | 
    
         
             
                    end
         
     | 
| 
       88 
89 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
                    def build_good_method(column, value)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    def build_good_method(dot, column, value)
         
     | 
| 
      
 91 
     | 
    
         
            +
                      dot ||= '.'
         
     | 
| 
       90 
92 
     | 
    
         
             
                      if column.include?('.')
         
     | 
| 
       91 
93 
     | 
    
         
             
                        table, column = column.split('.')
         
     | 
| 
       92 
94 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
                        "where 
     | 
| 
      
 95 
     | 
    
         
            +
                        "where#{dot}not(#{table}: { #{column}: #{value} })"
         
     | 
| 
       94 
96 
     | 
    
         
             
                      else
         
     | 
| 
       95 
     | 
    
         
            -
                        "where 
     | 
| 
      
 97 
     | 
    
         
            +
                        "where#{dot}not(#{column}: #{value})"
         
     | 
| 
       96 
98 
     | 
    
         
             
                      end
         
     | 
| 
       97 
99 
     | 
    
         
             
                    end
         
     | 
| 
       98 
100 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -30,6 +30,7 @@ module RuboCop 
     | 
|
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
                    def build!(ast)
         
     | 
| 
       32 
32 
     | 
    
         
             
                      raise "Unexpected type: #{ast.type}" unless ast.block_type?
         
     | 
| 
      
 33 
     | 
    
         
            +
                      return unless ast.body
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
                      each_table(ast) do |table_def|
         
     | 
| 
       35 
36 
     | 
    
         
             
                        next unless table_def.method?(:create_table)
         
     | 
| 
         @@ -127,7 +128,7 @@ module RuboCop 
     | 
|
| 
       127 
128 
     | 
    
         
             
                    private
         
     | 
| 
       128 
129 
     | 
    
         | 
| 
       129 
130 
     | 
    
         
             
                    def analyze_keywords!(node)
         
     | 
| 
       130 
     | 
    
         
            -
                      pairs = node. 
     | 
| 
      
 131 
     | 
    
         
            +
                      pairs = node.last_argument
         
     | 
| 
       131 
132 
     | 
    
         
             
                      return unless pairs.hash_type?
         
     | 
| 
       132 
133 
     | 
    
         | 
| 
       133 
134 
     | 
    
         
             
                      pairs.each_pair do |k, v|
         
     | 
| 
         @@ -158,7 +159,7 @@ module RuboCop 
     | 
|
| 
       158 
159 
     | 
    
         
             
                    end
         
     | 
| 
       159 
160 
     | 
    
         | 
| 
       160 
161 
     | 
    
         
             
                    def analyze_keywords!(node)
         
     | 
| 
       161 
     | 
    
         
            -
                      pairs = node. 
     | 
| 
      
 162 
     | 
    
         
            +
                      pairs = node.last_argument
         
     | 
| 
       162 
163 
     | 
    
         
             
                      return unless pairs.hash_type?
         
     | 
| 
       163 
164 
     | 
    
         | 
| 
       164 
165 
     | 
    
         
             
                      pairs.each_pair do |k, v|
         
     | 
| 
         @@ -12,10 +12,10 @@ module RuboCop 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  # So a cop that uses the loader should handle `nil` properly.
         
     | 
| 
       13 
13 
     | 
    
         
             
                  #
         
     | 
| 
       14 
14 
     | 
    
         
             
                  # @return [Schema, nil]
         
     | 
| 
       15 
     | 
    
         
            -
                  def load(target_ruby_version)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def load(target_ruby_version, parser_engine)
         
     | 
| 
       16 
16 
     | 
    
         
             
                    return @load if defined?(@load)
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
                    @load = load!(target_ruby_version)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @load = load!(target_ruby_version, parser_engine)
         
     | 
| 
       19 
19 
     | 
    
         
             
                  end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                  def reset!
         
     | 
| 
         @@ -38,23 +38,13 @@ module RuboCop 
     | 
|
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
                  private
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                  def load!(target_ruby_version)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  def load!(target_ruby_version, parser_engine)
         
     | 
| 
       42 
42 
     | 
    
         
             
                    path = db_schema_path
         
     | 
| 
       43 
43 
     | 
    
         
             
                    return unless path
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                    ast =  
     | 
| 
       46 
     | 
    
         
            -
                    Schema.new(ast) if ast
         
     | 
| 
       47 
     | 
    
         
            -
                  end
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                  def parse(path, target_ruby_version)
         
     | 
| 
       50 
     | 
    
         
            -
                    klass_name = :"Ruby#{target_ruby_version.to_s.sub('.', '')}"
         
     | 
| 
       51 
     | 
    
         
            -
                    klass = ::Parser.const_get(klass_name)
         
     | 
| 
       52 
     | 
    
         
            -
                    parser = klass.new(RuboCop::AST::Builder.new)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    ast = RuboCop::ProcessedSource.new(File.read(path), target_ruby_version, path, parser_engine: parser_engine).ast
         
     | 
| 
       53 
46 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
                     
     | 
| 
       55 
     | 
    
         
            -
                    buffer.source = path.read
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                    parser.parse(buffer)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    Schema.new(ast) if ast
         
     | 
| 
       58 
48 
     | 
    
         
             
                  end
         
     | 
| 
       59 
49 
     | 
    
         
             
                end
         
     | 
| 
       60 
50 
     | 
    
         
             
              end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rubocop-rails
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 2. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.24.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Bozhidar Batsov
         
     | 
| 
         @@ -10,7 +10,7 @@ authors: 
     | 
|
| 
       10 
10 
     | 
    
         
             
            autorequire:
         
     | 
| 
       11 
11 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       12 
12 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       13 
     | 
    
         
            -
            date:  
     | 
| 
      
 13 
     | 
    
         
            +
            date: 2024-03-25 00:00:00.000000000 Z
         
     | 
| 
       14 
14 
     | 
    
         
             
            dependencies:
         
     | 
| 
       15 
15 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       16 
16 
     | 
    
         
             
              name: activesupport
         
     | 
| 
         @@ -60,6 +60,26 @@ dependencies: 
     | 
|
| 
       60 
60 
     | 
    
         
             
                - - "<"
         
     | 
| 
       61 
61 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       62 
62 
     | 
    
         
             
                    version: '2.0'
         
     | 
| 
      
 63 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 64 
     | 
    
         
            +
              name: rubocop-ast
         
     | 
| 
      
 65 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 66 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 67 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 68 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 69 
     | 
    
         
            +
                    version: 1.31.1
         
     | 
| 
      
 70 
     | 
    
         
            +
                - - "<"
         
     | 
| 
      
 71 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 72 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
      
 73 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 74 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 75 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 76 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 77 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 78 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 79 
     | 
    
         
            +
                    version: 1.31.1
         
     | 
| 
      
 80 
     | 
    
         
            +
                - - "<"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
       63 
83 
     | 
    
         
             
            description: |
         
     | 
| 
       64 
84 
     | 
    
         
             
              Automatic Rails code style checking tool.
         
     | 
| 
       65 
85 
     | 
    
         
             
              A RuboCop extension focused on enforcing Rails best practices and coding conventions.
         
     | 
| 
         @@ -225,7 +245,7 @@ metadata: 
     | 
|
| 
       225 
245 
     | 
    
         
             
              homepage_uri: https://docs.rubocop.org/rubocop-rails/
         
     | 
| 
       226 
246 
     | 
    
         
             
              changelog_uri: https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md
         
     | 
| 
       227 
247 
     | 
    
         
             
              source_code_uri: https://github.com/rubocop/rubocop-rails/
         
     | 
| 
       228 
     | 
    
         
            -
              documentation_uri: https://docs.rubocop.org/rubocop-rails/2. 
     | 
| 
      
 248 
     | 
    
         
            +
              documentation_uri: https://docs.rubocop.org/rubocop-rails/2.24/
         
     | 
| 
       229 
249 
     | 
    
         
             
              bug_tracker_uri: https://github.com/rubocop/rubocop-rails/issues
         
     | 
| 
       230 
250 
     | 
    
         
             
              rubygems_mfa_required: 'true'
         
     | 
| 
       231 
251 
     | 
    
         
             
            post_install_message:
         
     | 
| 
         @@ -243,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       243 
263 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       244 
264 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       245 
265 
     | 
    
         
             
            requirements: []
         
     | 
| 
       246 
     | 
    
         
            -
            rubygems_version: 3. 
     | 
| 
      
 266 
     | 
    
         
            +
            rubygems_version: 3.3.26
         
     | 
| 
       247 
267 
     | 
    
         
             
            signing_key:
         
     | 
| 
       248 
268 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       249 
269 
     | 
    
         
             
            summary: Automatic Rails code style checking tool.
         
     |