Metaprogramming as a tool for refactoring Ruby on Rails controllers

Once you learn about metaprogramming in Ruby on rails you probably want to use it all the time. Once I learned about it, I went looking for places in my code to use it. Here is a simple example of a controller that is in need of some love. This is a controller for a blog or a news site.

A few methods have been added which get the top, latest and trending articles respectively. All methods call another method on the Article model to select articles. This example does not include any pagination and other things that you usually do in these methods.

As you can see, all methods pretty much do the same thing: Call a method on Article and set the returned articles to the @articles instance variable.  In a more realistic example the methods probably have more code in them and there might be a few more to handle other cases, such as articles in a specific category or the worst articles. I’m going to show you one way to remove these methods. There are other ways to do this, but I am going to focus on one that uses pure Ruby and a bit of metaprogramming magic.

First of all, as always, make sure you have tests for these methods before you start messing around with them. This is critical when you do any refactoring and even more so when you start using metaprogramming tricks to clean up your code.

To refactor these methods,  define_method will be used to define new methods on the ArticlesController at runtime. Create the following method in the ArticlesController class:

define_method will create a new method on the current object. Since you want the created methods to be available in all instances of ArticlesController, then define_top_method needs to be defined on the class ArticlesController. It takes an argument name and then calls define_method to create a new method on the current object. This method will use send to call the correct method on the Article model, because that method has the same name as the controller action. If this is not the case, then you can simply use another parameter in define_top_method to set the name of the method to call on Article.

You can now replace all three of the original methods above with the following:

Make sure that these three method calls are made below the definition of define_top_method because you call them directly on the class and the called method must exist before that it possible.

So far this is pretty good, but we can make this even more compact by changing define_top_method like so:

define_top_method now takes any number of arguments and will create a method for each of them. The three calls to define_top_method can now be replaced by one and the final class will look like this:

This is arguably less readable than the original code, but you have to imagine that each of the three original methods probably consist of a few more lines of code and there will probably be more of them.

If you want to learn more about define_method, or metaprogramming in Ruby in general, then I recommend the book Metaprogramming Ruby by Paolo Perrotta. It teaches you everything you need to know about metaprogramming in Ruby.

Read More Post

STAY CONNECTED

Most Popular

Why Serviced Apartments Are the Perfect Choice for Long-Term Stays in Singapore – Everything You Need to Know
17 Dec

Why Serviced Apartments Are the Perfect Choice for Long-Term Stays in Singapore – Everything You Need to Know

If you’re heading to Singapore for a few weeks or many months, maybe for work or study or just to

Manifesting Your Dream Career: Finding Your Passion And Purpose
01 Aug

Manifesting Your Dream Career: Finding Your Passion And Purpose

Are you passionate about finding your dream career? Manifesting can help you align your career with your passions and purpose.

Revolutionizing Your Ride: Expert Auto Service At Carolina Auto Service
27 Feb

Revolutionizing Your Ride: Expert Auto Service At Carolina Auto Service

Finding a reliable auto service provider is paramount in the bustling world of vehicle maintenance and repair. That's where Carolina

Floratam: The Robust Grass Solution From Council Growers SOD
25 Jan

Floratam: The Robust Grass Solution From Council Growers SOD

Floratam grass, a popular St. Augustine variety, has become a go-to choice for homeowners and landscapers seeking a lush, durable

Carolina Mobile Autoservice: Your Go-To For Expert Brake Service Repair
25 Jan

Carolina Mobile Autoservice: Your Go-To For Expert Brake Service Repair

For vehicle owners, the braking system is among the most critical components for safety and performance. Carolina Mobile Autoservice, a

Safeguarding Your Property: Expert Water Damage Services By MBC Capital
24 Jan

Safeguarding Your Property: Expert Water Damage Services By MBC Capital

Water damage can significantly impact homes and businesses, often leaving a trail of destruction and disruption in its wake. Understanding