Using multiple namespaces will require to have also namespaces views.
For exemple, if you have an Admin
namespace, with a Admin::ProjectsController
with a show
action that also exists in non namespaced ProjecsController
, you cannot render views/projects/show.html.erv
from Admin::ProjecsController
.
The researched behavior is to try to render the views/admin/projects/show.html.erb
, and, if it doesn't exist, fallback to views/projects/show.html.erb
Use a ViewResolver in /whateveryouwant
. I choosed to put it in lib/resolvers/admin_views_resolver.rb
:
class Resolvers::AdminViewsResolver < ::ActionView::FileSystemResolver
def initialize
super('app/views')
end
def find_templates(name, prefix, partial, details)
prefix = prefix.sub(/^admin\//, '')
super(name, prefix, partial, details)
end
end
Then make it autoload in application/config.rb
:
# Add lib directory in autoload_paths
config.autoload_paths << File.join(config.root, 'lib')
And finally, instanciate it in our(s) controller(s) :
class Admin::BaseController < ApplicationController
append_view_path Resolvers::AdminViewsResolver.new
end
We're telling to Rails to use a this view resolver for our Admin::BaseController
, which is the parent controller for all our controllers under Admin
namespace.
This will not break anything, because we call super('app/views')
in the initialize
function of the resolver. So, Rails will try to find the views/admin/projects/show.html.erb
, but then, only if there is no such view, will call the find_templates
method from the resolver, which trim admin
from prefix variable (the prefix variable contains the original path to the template).