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