Mimicking the ‘devise_for’ Devise routes helper
Mounting a path outside your Rails Engine’s namespace
TL;DR add a method in ActionRouting::Dispatch::Mapper
Devise has this nifty helper that you can use in your config/routes.rb
file to mount paths:
# config/routes.rbdevise_for :users
At Bloom we we’re building a Rails engine that helps Rails apps to become Stellar Anchors. One of the requirements in becoming part of the Stellar ecosystem is to adhere to their protocol; a part of that protocol requires services to mount a /.well-known/stellar
endpoint that contains a toml
file. The toml
file specifies where 3rd-parties can check where they can transact/integrate with your organization using Stellar.
With that said: it would be nice if the users of that Rails engine could have that /.well-known/stellar
easily in their app . Since Rails engines get mounted via mount MyEngine => "/my_engine"
you can’t really supply paths outside of that isolated namespace unless you do something really funky.
It would be nice if we could mimic Devise’s devise_for
# config/initializers/my_engine.rb# or whatever you use to require it in your app
MyEngine.setup do
...
end# config/routes.rbRails.application.routes.draw do
...
mount MyEngine => "/my_engine"
mount_some_path_outside_my_engine
...
end
Opening up the Devise gem, you could see that they’ve actually added devise_for
in ActionDispatch::Routing::Mapper
and it calls resources
and other familiar Rails route methods. It’s really educational just reading through it.
So, in our Rails engine, we could do something like:
module ActionDispatch
module Routing
class Mapper def mount_some_path_outside_my_engine
# stellar_base/home#show is a controller inside
# the Rails Engine
get(
"/.well-known/stellar" => "stellar_base/home#show",
:as => :stellar_toml,
:defaults => { format: "toml" },
)
end end
end
end
You can then write an spec/acceptance
for this in your Rails engine, so people would know and expect that the helpers do mount a path outside your engine namespace.