Reputation: 8595
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
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
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
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