231

Is there a way to figure out what the current controller is from within the view?

For an example of why I would want to know this: if several controllers share the same layout, I may have a part in the layout ERB file where I want to highlight the current page's menu item based on the controller.

Maybe that is a bad approach. If so, what is the more preferred way to do this?

I'm interested to know about getting the name of the current controller either way, though.

(Obviously I could put something like @controller_name = 'users' in each controller; but that seems like the sort of thing Rails would've already done behind the scenes. So I'm just wondering if there's a built-in way.)

Arslan Ali
  • 17,418
  • 8
  • 58
  • 76
Dan Tao
  • 125,917
  • 54
  • 300
  • 447

5 Answers5

286

controller_name holds the name of the controller used to serve the current view.

mb21
  • 34,845
  • 8
  • 116
  • 142
Anubhaw
  • 5,978
  • 1
  • 29
  • 38
  • 96
    Actually is bad practice to use `params` in view. Please use `controller_name` instead – coorasse May 02 '14 at 13:15
  • 1
    @coorasse is right, for sure the information is there, but relying on controller_name is better – Cec Jul 15 '16 at 07:56
276

Use controller.controller_name

In the Rails Guides, it says:

The params hash will always contain the :controller and :action keys, but you should use the methods controller_name and action_name instead to access these values

ActionController Parameters

So let's say you have a CSS class active , that should be inserted in any link whose page is currently open (maybe so that you can style differently) . If you have a static_pages controller with an about action, you can then highlight the link like so in your view:

<li>
  <a class='button <% if controller.controller_name == "static_pages" && controller.action_name == "about" %>active<%end%>' href="/about">
      About Us
  </a>
</li>
Musili Alfred M.
  • 3,085
  • 1
  • 15
  • 12
  • 25
    If you have your controller behind a namespace like this: `Admin::Orders` then `controller_name` and `params[:controller]` will be `"orders"` and `"admin/orders"` respectively. – Viktor Sep 23 '13 at 08:10
  • 9
    I just tried to use this and `Admin::UsersController` actually has a `controller_name` of `users` and a `controller_path` of `admin/users` in Rails 4.1.0. – Brandon Jul 03 '14 at 19:46
94
#to get controller name:
<%= controller.controller_name %>
#=> 'users'

#to get action name, it is the method:
<%= controller.action_name %>
#=> 'show'


#to get id information:
<%= ActionController::Routing::Routes.recognize_path(request.url)[:id] %>
#=> '23'

# or display nicely
<%= debug Rails.application.routes.recognize_path(request.url) %>

reference

Juanito Fatas
  • 9,419
  • 9
  • 46
  • 70
Thaha kp
  • 3,689
  • 1
  • 26
  • 25
  • 1
    To get the id, ActionController::Routing::Routes no longer works. You can do this: <%= request.path_parameters[:id] %> – rmcsharry Apr 07 '16 at 10:16
7

controller_path holds the path of the controller used to serve the current view. (ie: admin/settings).

and

controller_name holds the name of the controller used to serve the current view. (ie: settings).

1

If you want to use all stylesheet in your app just adds this line in application.html.erb. Insert it inside <head> tag

  <%= stylesheet_link_tag  controller.controller_name , media: 'all', 'data-turbolinks-track': 'reload' %>

Also, to specify the same class CSS on a different controller
Add this line in the body of application.html.erb

  <body class="<%= controller.controller_name %>-<%= controller.action_name %>">

So, now for example I would like to change the p tag in 'home' controller and 'index' action. Inside index.scss file adds.

.nameOfController-nameOfAction <tag> { }

 .home-index p {
        color:red !important;
      }
Sami
  • 115
  • 1
  • 3