Skip to content

Make UrlHelpers generator Rails Engine aware #474

Open
@paracycle

Description

@paracycle

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 the Rails.application one.

In order to be able to properly represent this, we need to do the following:

  • Loop over all the Rails engines inside the application
  • For each engine:
    • Grab the helpers modules engine.routes.named_routes.url_helpers_module and engine.routes.named_routes.path_helpers_module and give them engine specific names, like XXX::Engine::GeneratedUrlHelpersModule.
    • Discover all the named modules that include those url helper modules and gather them as constants to decorate.
    • In decorate, create module definitions for the app and engine url helpers and add includes for them for the modules that include them.

Test Case

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

should create:

# generated_path_helpers_module.rbi
# typed: strong

module GeneratedPathHelpersModule
  include ::ActionDispatch::Routing::UrlFor
  include ::ActionDispatch::Routing::PolymorphicRoutes

  sig { params(args: T.untyped).returns(String) }
  def edit_index_path(*args); end

  sig { params(args: T.untyped).returns(String) }
  def index_path(*args); end

  sig { params(args: T.untyped).returns(String) }
  def new_index_path(*args); end

  sig { params(args: T.untyped).returns(String) }
  def articles_path(*args); end
end
# generated_url_helpers_module.rbi
# typed: strong

module GeneratedUrlHelpersModule
  include ::ActionDispatch::Routing::UrlFor
  include ::ActionDispatch::Routing::PolymorphicRoutes

  sig { params(args: T.untyped).returns(String) }
  def edit_index_url(*args); end

  sig { params(args: T.untyped).returns(String) }
  def index_url(*args); end

  sig { params(args: T.untyped).returns(String) }
  def new_index_url(*args); end

  sig { params(args: T.untyped).returns(String) }
  def articles_url(*args); end
end
# article/engine/generated_path_helpers_module.rbi
# typed: strong

module Article::Engine::GeneratedPathHelpersModule
  include ::ActionDispatch::Routing::UrlFor
  include ::ActionDispatch::Routing::PolymorphicRoutes

  sig { params(args: T.untyped).returns(String) }
  def edit_article_path(*args); end

  sig { params(args: T.untyped).returns(String) }
  def article_path(*args); end

  sig { params(args: T.untyped).returns(String) }
  def new_article_path(*args); end

  sig { params(args: T.untyped).returns(String) }
  def articles_path(*args); end
end
# article/engine/generated_url_helpers_module.rbi
# typed: strong

module Article::Engine::GeneratedUrlHelpersModule
  include ::ActionDispatch::Routing::UrlFor
  include ::ActionDispatch::Routing::PolymorphicRoutes

  sig { params(args: T.untyped).returns(String) }
  def edit_article_url(*args); end

  sig { params(args: T.untyped).returns(String) }
  def article_url(*args); end

  sig { params(args: T.untyped).returns(String) }
  def new_article_url(*args); end

  sig { params(args: T.untyped).returns(String) }
  def articles_url(*args); end
end

and the corresponding includes to the modules that include the above helpers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp-wantedWe support this change, and welcome community contributions for it.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions