Rails: How to get the model class name based on the controller class name?

Ruby on-RailsRuby on-Rails-3

Ruby on-Rails Problem Overview


class HouseBuyersController < ...
  def my_method
    # How could I get here the relevant model name, i.e. "HouseBuyer" ?
  end
end

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

This will do it:

class HouseBuyersController < ApplicationController
  
  def index
    @model_name = controller_name.classify
  end

end

This is often needed when abstracting controller actions:

class HouseBuyersController < ApplicationController

  def index
    # Equivalent of @house_buyers = HouseBuyer.find(:all)
    objects = controller_name.classify.constantize.find(:all)
    instance_variable_set("@#{controller_name}", objects)
  end

end

Solution 2 - Ruby on-Rails

If your controller and model are in the same namespace, then what you want is

controller_path.classify

controller_path gives you the namespace; controller_name doesn't.

For example, if your controller is

Admin::RolesController

then:

controller_path.classify # "Admin::Role" # CORRECT
controller_name.classify # "Role"        # INCORRECT

Solution 3 - Ruby on-Rails

It's a bit of a hack, but if your model is named after your controller name then:

class HouseBuyersController < ApplicationController
  def my_method
    @model_name = self.class.name.sub("Controller", "").singularize
  end
end

... would give you "HouseBuyer" in your @model_name instance variable.

Again, this makes a huge assumption that "HouseBuyersController" only deals with "HouseBuyer" models.

Solution 4 - Ruby on-Rails

For namespaces working:

def resource_class
 controller_path.classify.constantize
end

Solution 5 - Ruby on-Rails

The accepted solution did not work for me as my controller and model was namespaced. Instead, I came up with the following method:

def controllers_model
  (self.class.name.split('::')[0..-2] << controller_name.classify).join('::')
end

Solution 6 - Ruby on-Rails

This is not possible if you are using the default MVC, which your code doesn't seem to follow. Your controller seems to be a model but maybe you just got a type there. Anyway, controllers and models are fundamentally separated in Rails MVC so controllers cannot know which model they are associated with.

For example you could have a model named post. This can have a controller posts_controller or could have a controller like articles_controller. Rails only knows about models when you def the actual code in the controller such as

def index
  @posts = Post.all
  @posts = Article.all
end  

In rails standard controllers there is no way to know what the model is.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMisha MoroshkoView Question on Stackoverflow
Solution 1 - Ruby on-RailsmalclockeView Answer on Stackoverflow
Solution 2 - Ruby on-RailsMattView Answer on Stackoverflow
Solution 3 - Ruby on-RailsScottView Answer on Stackoverflow
Solution 4 - Ruby on-RailshachpaiView Answer on Stackoverflow
Solution 5 - Ruby on-RailsstoffusView Answer on Stackoverflow
Solution 6 - Ruby on-RailsthenengahView Answer on Stackoverflow