0

I have this rails controller:

module Admin
  module Settings
    class PrintersController < ApplicationController # BaseController
    end
  end
end

I believe I should be able to match a layout for it as

app/views/layouts/admin/settings.html.erb

but this does not work. I can get

app/views/layouts/admin/settings/printers.html.erb

to work but I want a common layout for all settings.

what am I doing wrong?

From the documentation:

Parent Namespaced Layouts: If a layout is not found at the controller level, Rails will then traverse up the namespace hierarchy, looking for layouts that match the parent namespaces. For instance, Admin::Products::ItemsController might look for app/views/layouts/admin/products.html.erb, and then app/views/layouts/admin.html.erb. This behavior is often utilized by defining a base controller for a namespace (e.g., Admin::BaseController) and specifying a layout within that base controller.

5
  • While I did not dive into this at all based on the way you have laid it out. Have you considered following the last sentence of the documentation and simply injecting an inheritance layer? e.g. class SettingsController < ApplicationController; end and then class PrintersController < SettingsController? This seems like the easiest solution with the least amount of "magic" involved. Commented Nov 6 at 19:37
  • Not sure what "magic" you refer to Commented Nov 6 at 22:57
  • 1
    where is this documentation from? Layout is inherited from a superclass, not module parent. api.rubyonrails.org/classes/ActionView/… Commented Nov 6 at 23:53
  • @MitchVanDuyn rails is full of magic, like, as your post suggests, parsing a class name and walking a directory tree to try and find a layout. Due to it's design it has lead many to avoid being specific about intentions and instead relying on rails inferences. In this case adding a specific class and more over even a specific layout would solve this problem promptly and with significantly more clarity in the future. Commented Nov 7 at 14:17
  • whatever happened to convention over configuration? Back in the day, rails just worked, now, it seems not so much. Well thanks anyway! Commented Nov 7 at 16:59

1 Answer 1

0

From the docs:

For instance, if you have PostsController and a template named app/views/layouts/posts.html.erb, that template will be used for all actions in PostsController and controllers inheriting from PostsController.

If you use a module, for instance Weblog::PostsController, you will need a template named app/views/layouts/weblog/posts.html.erb.

Since all your controllers inherit from ApplicationController, they will use app/views/layouts/application.html.erb if no other layout is specified or provided.

In other words, Rails convention suggests layout file name as controller name and also supports inheritance

So for your Admin::Settings::PrintersController layout inheritance:

  • app/views/layouts/admin/settings/printers.html.erb
  • app/views/layouts/application.html.erb

app/views/layouts/admin/settings.html.erb is valid only for Admin::SettingsController and all its children

Sign up to request clarification or add additional context in comments.

1 Comment

I accept and understand the answer. My problem is that it was/is unclear whether the search for the layout is based on the inheritence tree or the name space tree. I had thought logically that it was the name space tree since that (I think) covers both cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.