rails icon indicating copy to clipboard operation
rails copied to clipboard

Document for rails >= 7.1 how to run an application in a mounting point different to "/". This will avoid duplication of the relative root path in routes helpers.

Open vtamara opened this issue 7 months ago • 15 comments

Simple case

(1) An engine that has a route (let's say articles_path pointing to /articles) and (2) an application mounted on a relative route (let's say /a/) that mounts the engine on that same route by a) using config.relative_url_root="/a" in config/application.rb as well as defining a scope "/a" in config/routes.rb and mounting the engine on the same route.

In the application articles_path will be /a/a/articles instead of /a/articles as it is with rails 7.0

Steps to reproduce

  1. With rails 7 generate part of the engine described at https://edgeguides.rubyonrails.org/engines.html:
    rails plugin new engine49688 --mountable
    cd engine49688
    bundle
    bin/rails generate scaffold article title:string text:text
    bin/rails db:migrate
    
    If you prefer you can clone this engine from this repository https://gitlab.com/vtamara/engine49688 or check more details of how we generated it in the README.md
  2. With rails 7 generate part of the application described at https://edgeguides.rubyonrails.org/engines.html:
    cd ..
    rails new app49688 --minimal --skip-keeps
    cd app49688
    bundle add engine49688 --path=../engine49688
    bundle
    bin/rails engine49688:install:migrations
    bin/rails g scaffold user username:string name:string
    bin/rails db:migrate
    
    In this application make sure that the relative root is /a by
    • Adding config.relative_url_root = "/a/" to config/application.rb
    • Using that route as main scope in config/routes.rb and to mount on it the engine, i.e the contents of the file is:
      Rails.application.routes.draw do            
        scope "/a" do
          resources :users
        end
        mount Engine49688::Engine => "/a", as: :engine49688
      end
      
    And create the test test/controllers/routes_test.rb with:
     require "test_helper"
     class RoutesTest < ActionDispatch::IntegrationTest
    
       test "articles_path" do
         assert_equal '/a/articles', engine49688.articles_path
       end
     end
    
    If you prefer you can also clone this application from https://gitlab.com/vtamara/app49688 or check details on how we generated it and use it in the README.md.
  3. Run the test with rails 7 and it wil pass
  4. Update the application to rails 7.1 by changing in the Gemfile the line gem "rails", "~> 7.0.8" with gem "rails", "~> 7.1" and running bundle
  5. Run the same test and it will fail

Expected behavior

With rails 7.1 the test should pass, i.e engine49688.articles_path should be /a/articles as it is with Rails 7.0:

% bin/rails test test/controllers/routes_test.rb
Running 1 tests in a single process (parallelization threshold is 50)
Run options: --seed 22764

# Running:

.

Finished in 0.345284s, 2.8962 runs/s, 2.8962 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

Actual behavior

 % bin/rails test test/controllers/routes_test.rb
...
Running 1 tests in a single process (parallelization threshold is 50)
Run options: --seed 2957

# Running:

F

Failure:
RoutesTest#test_articles_path [/home/vtamara/comp/rails/tmp/app49688/test/controllers/routes_test.rb:6]:
Expected: "/a/articles"
  Actual: "/a/a/articles"


bin/rails test test/controllers/routes_test.rb:5



Finished in 0.206910s, 4.8330 runs/s, 4.8330 assertions/s.
1 runs, 1 assertions, 1 failures, 0 errors, 0 skips 

In the test articles_path duplicates the relative root.

System configuration

Rails version: 7.1

Ruby version: 3.2.2

vtamara avatar Oct 18 '23 15:10 vtamara