Ruby on Rails: Grabbing the model object using the controller name

Posted on January 09, 2008

I found myself in a situation where I was creating basically the same method in many of my controllers, the only difference being the name of the model object. For example:

class ArticlesController

 # .... cut 

 def set_recommended(is_recommended)
    @article.recommended = is_recommended
    @article.save    
    respond_to do |format|
      format.js { render :nothing => true }
    end    
 end

class MoviesController
 # .... cut 

 def set_recommended(is_recommended)
    @movie.recommended = is_recommended
    @movie.save    
    respond_to do |format|
      format.js { render :nothing => true }
    end    
 end

end

So, I want to refactor this code, and create one method for this in the application.rb file – but how to refer to the @movie and @article objects?

Simply by using the instance_variable_get method! You simply pass in a string with the name of the method, and it returns the instance variable.

Here’s how the new method looked within the application.rb file.
class ApplicationController
 # .... cut 

  def set_recommended(is_recommended)
    object = instance_variable_get("@#{self.controller_class_name.chomp("Controller").singularize.underscore}")
    object.recommended = is_recommended
    object.save    
    respond_to do |format|
      format.js { render :nothing => true }
    end        
  end

end

Of course, this only works for controllers and model names that follow the singular, plural convention (i.e. model name is article and controller name is ArticlesController)