Kostas
Kostas

Reputation: 8595

How to retrieve the controller class from within a view/helper in Rails 3?

I know about controller_name returning a string containing the controller's name but how can I retrieve the controller class (or object) from within a helper?

EDIT: The solution should also work when the controller is namespaced (eg. Admin::PostsController)

Upvotes: 1

Views: 652

Answers (3)

tbuehlmann
tbuehlmann

Reputation: 9110

You can use the constantize method, like:

controller_name.constantize

Though I'm not sure how it will behave if you have a namespaced controller.

Update:

That one won't work for all controller names and/or namespaces. Though one can use the #controller method in combination with #class:

controller.class

Upvotes: 3

Marek Příhoda
Marek Příhoda

Reputation: 11198

In pure Ruby, because class names are constants, you can do this to get the class from a string:

classname = 'Posts'
p Kernel.const_get(classname).methods

There is a nice shortcut in Rails, constantize for just this:

p 'Posts'.constantize.methods

If the classname is eg 'editable_file', first call the camelize method:

p 'editable_file'.camelize.constantize  # EditableFile
p 'extensions/editable_file'.camelize.constantize  # Extensions::EditableFile

EDIT: If you really want to get the controller name un-demodulized, then this code in config/initializers/controller_name.rb should ensure it:

class ActionController::Metal
  def self.controller_name
    # @controller_name ||= self.name.demodulize.sub(/Controller$/, '').underscore
    @controller_name ||= self.name.sub(/Controller$/, '').underscore
  end
end

Upvotes: 1

Joshua Cheek
Joshua Cheek

Reputation: 31756

A view probably shouldn't need to do this. Ideally whatever you're trying to do in the view that expects this, you would instead do in the controller.

Trying to think about why you'd want to do this, the best answer I can think of is that you want to invoke a helper method you've defined in the controller. There already exists a construct to do this, use helper_method.

For pretty much anything else, the controller should provide that data to the view. Not the view pulling it out of the controller. (e.g. even though you shouldn't need the class, the controller could provide it with @controller_class = self.class, which would then be available to the view)

Upvotes: 1

Related Questions