class RuboCop::Cop::Rails::RootJoinChain


Rails.public_path.join(‘path’, to, ‘file.pdf’)
Rails.public_path.join(‘path’, ‘file.pdf’)
Rails.root.join(‘db’, migrate, ‘migration.rb’)
Rails.root.join(‘db’, ‘schema.rb’)
# good
Rails.public_path.join(‘path’).join(to).join(‘file.pdf’)
Rails.public_path.join(‘path’).join(‘file.pdf’)
Rails.root.join(‘db’).join(migrate).join(‘migration.rb’)
Rails.root.join(‘db’).join(‘schema.rb’)
# bad
@example
Use a single ‘#join` instead of chaining on `Rails.root` or `Rails.public_path`.

def evidence(node)

def evidence(node)
  # Are we at the *end* of the join chain?
  return if join?(node.parent)
  # Is there only one join?
  return if rails_root?(node.receiver)
  all_args = []
  while (args = join?(node))
    all_args = args + all_args
    node = node.receiver
  end
  rails_root?(node) do
    yield(node, all_args)
  end
end

def on_send(node)

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