Open paracycle opened 3 years ago
It turns out that for the above test case also need to generate:
module GeneratedMountedHelpers < ActionDispatch::Routing::RouteSet::MountedHelpers
sig { returns(Article::Engine::RoutesProxy) }
def articles; end
end
with:
class Article::Engine::GeneratedRoutesProxy < ActionDispatch::Routing::Proxy
include Article::Engine::GeneratedPathHelpersModule
include Article::Engine::GeneratedUrlHelpersModule
end
and the GeneratedMountedHelpers
module being mixed into all controllers as a helper module.
Btw, the way to discover all this info about Rails engines is:
$ dev c
👩💻 Running bin/console from dev.yml
[1] pry(main)> require "rails"
=> true
[2] pry(main)> module Article
class Engine < ::Rails::Engine
isolate_namespace Article
routes.draw do
resource :articles
end
end
end
class Application < Rails::Application
routes.draw do
resource :index
mount Article::Engine, at: "/", as: "articles"
end
end
=> nil
[3] pry(main)> Rails.application.railties.grep(Rails::Engine)
=> [#<Article::Engine:0x00007f80193c0d48
@_all_autoload_paths=nil,
@_all_load_paths=nil,
@app=nil,
@app_build_lock=#<Thread::Mutex:0x00007f80193c0be0>,
@config=
#<Rails::Engine::Configuration:0x00007f80194f3c10
@generators=
#<Rails::Configuration::Generators:0x00007f80194f38a0
@after_generate_callbacks=[],
@aliases={},
@api_only=false,
@colorize_logging=true,
@fallbacks={},
@hidden_namespaces=[],
@options={},
@templates=[]>,
@javascript_path="javascript",
@middleware=#<Rails::Configuration::MiddlewareStackProxy:0x00007f80194f3648 @delete_operations=[], @operations=[]>,
@root=#<Pathname:/Users/ufuk/src/github.com/Shopify/shopify-types>>,
@env_config=nil,
@helpers=nil,
@routes=#<ActionDispatch::Routing::RouteSet:0x00007f80194f3490>>]
[4] pry(main)> Rails.application.railties.grep(Rails::Engine).first.routes.named_routes.path_helpers_module.instance_methods(false)
=> [:edit_articles_path, :new_articles_path, :articles_path]
[5] pry(main)> Rails.application.railties.grep(Rails::Engine).first.routes.named_routes.url_helpers_module.instance_methods(false)
=> [:articles_url, :edit_articles_url, :new_articles_url]
[6] pry(main)> Rails.application.routes.mounted_helpers.instance_methods(false)
=> [:_articles, :articles]
It turns out that Rails Engines have their own router and the controllers, etc inside a Rails Engine get an engine specific
url_helper
module included, not theRails.application
one.In order to be able to properly represent this, we need to do the following:
engine.routes.named_routes.url_helpers_module
andengine.routes.named_routes.path_helpers_module
and give them engine specific names, likeXXX::Engine::GeneratedUrlHelpersModule
.decorate
, create module definitions for the app and engine url helpers and add includes for them for the modules that include them.Test Case
should create:
and the corresponding includes to the modules that include the above helpers.