rails
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.
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
- With rails 7 generate part of the engine described at https://edgeguides.rubyonrails.org/engines.html:
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.mdrails plugin new engine49688 --mountable cd engine49688 bundle bin/rails generate scaffold article title:string text:text bin/rails db:migrate
- With rails 7 generate part of the application described at https://edgeguides.rubyonrails.org/engines.html:
In this application make sure that the relative root iscd .. 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
/a
by- Adding
config.relative_url_root = "/a/"
toconfig/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
test/controllers/routes_test.rb
with:
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.require "test_helper" class RoutesTest < ActionDispatch::IntegrationTest test "articles_path" do assert_equal '/a/articles', engine49688.articles_path end end
- Adding
- Run the test with rails 7 and it wil pass
- Update the application to rails 7.1 by changing in the
Gemfile
the linegem "rails", "~> 7.0.8"
withgem "rails", "~> 7.1"
and runningbundle
- 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