Class: RuboCop::Cop::Rails::RootJoinChain

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
RangeHelp
Defined in:
lib/rubocop/cop/rails/root_join_chain.rb

Overview

Use a single ‘#join` instead of chaining on `Rails.root` or `Rails.public_path`.

Examples:

# bad
Rails.root.join('db').join('schema.rb')
Rails.root.join('db').join(migrate).join('migration.rb')
Rails.public_path.join('path').join('file.pdf')
Rails.public_path.join('path').join(to).join('file.pdf')

# good
Rails.root.join('db', 'schema.rb')
Rails.root.join('db', migrate, 'migration.rb')
Rails.public_path.join('path', 'file.pdf')
Rails.public_path.join('path', to, 'file.pdf')

Constant Summary collapse

MSG =
'Use `%<root>s.join(...)` instead of chaining `#join` calls.'
RESTRICT_ON_SEND =
%i[join].to_set.freeze

Instance Method Summary collapse

Instance Method Details

#join?(node) ⇒ Object



35
36
37
# File 'lib/rubocop/cop/rails/root_join_chain.rb', line 35

def_node_matcher :join?, <<~PATTERN
  (send _ :join $...)
PATTERN

#on_send(node) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/rubocop/cop/rails/root_join_chain.rb', line 39

def on_send(node)
  evidence(node) do |rails_node, args|
    add_offense(node, message: format(MSG, root: rails_node.source)) do |corrector|
      range = range_between(rails_node.loc.selector.end_pos, node.source_range.end_pos)
      replacement = ".join(#{args.map(&:source).join(', ')})"

      corrector.replace(range, replacement)
    end
  end
end

#rails_root?(node) ⇒ Object



30
31
32
# File 'lib/rubocop/cop/rails/root_join_chain.rb', line 30

def_node_matcher :rails_root?, <<~PATTERN
  (send (const {nil? cbase} :Rails) {:root :public_path})
PATTERN