Rails Helpers – what are they and what are they used for?

Olivia Mattiazzo - Sep 4 - - Dev Community

Has it ever happened to you that you use a concept in your preferred programming language without really understanding why you’re using it? Or what exactly it does? This recently happened to me when I was tasked with refactoring someone else’s code: I didn’t quite understand what Rails modules were or what Helpers were for. So, I took some time to study this and prepared this summary on what Rails Helpers are and what they are used for!

A small elf helper


That method to give you a little help.


Organizing the party

In this post, I intend to cover, in the following order:

  1. A general explanation of what Rails Helper methods are and the best practices associated with them
  2. Delve into more details about Ruby Modules and their importance within the language
  3. Touch on the topic of Composition vs. Inheritance, which is always good to keep fresh in mind

What are Helpers in Rails?

Helpers are methods primarily used to share reusable code between the views in your project. It's important to note that Helpers don't necessarily need to be created by developers: there are already some native methods provided by Rails to make our lives easier.

Examples of native Rails Helpers:

time_ago_in_words(Time.now)
# "less than a minute"

number_to_human(10_000)
# "10 Thousand"
Enter fullscreen mode Exit fullscreen mode

Helper methods are also very important when created by programmers themselves, as they help apply the DRY principle within the project's code. By doing so, you condense a portion of the logic into a single place instead of having it scattered across various parts of the code.

Clothes hanging on a line


DRY – Don’t Repeat Yourself

Writing Your Own Helpers

There is a specific directory for creating your own Helpers in Rails, which is the app/helpers directory. Inside this folder, you need to create a new file and, within a module, develop what you need. Everything inside it automatically becomes visible to the views in your project.

For example: we went to app/helpers and created the file user_helper.rb, which will contain all our user-related helpers. Inside it, we will build the following module:

module UserHelper
  def format_name(user)
    if user.gender == "M"
      "Mr. #{user.name}"
    else
      "Mrs. #{user.name}"
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

There is also a generic option, useful if your application is small and you need only a few Helpers, for example, which is to put everything inside the ApplicationHelper. This is a base module in Rails, ready to receive any future helpers you develop.

Best Practices for Using Helpers

When should you use and/or create a helper?

Whenever you have reusable logic that produces HTML code. Most of the time, this involves code related to string formatting or view elements that are conditional. It's a good idea to encapsulate this logic within a helper to avoid having it scattered and repeated throughout your application.

A line messed up


Organize your stuff

Use and abuse of parameters

It's a way to clearly specify from the beginning what your method needs, reducing the risk of encountering errors related to missing variables while working with information within your helper.

Try not to use helpers in Controllers

Some developers believe in the concept of Controller Helpers, which are helpers more focused on logic rather than presentation. It's also possible to use view helpers directly in controllers by invoking them with the helpers object. For example:

class UsersController
  def index
    helpers.time_ago_in_words(Time.now)
  end
end
Enter fullscreen mode Exit fullscreen mode

RubyGuides advises caution when doing this, as it can be considered a design problem, suggesting the use of a Ruby object instead, although it doesn't provide further details on why. I also think it's worth noting this warning, and when in doubt, keep helpers confined to views, OK?

What are Ruby Modules?

Throughout this article, I've talked a lot about Ruby modules and how important they are when writing helpers. Then I realized that I didn't know what the heck a Ruby module was. So, I did some research and am sharing this important extra bit on what it is and what this useful little keyword is for.

A module is a Ruby container used to store methods, variables, and constants. It's similar to a class, but unlike a class, a module cannot be instantiated. It's somewhat similar to the concept of static in .NET.

Modules have two main purposes in Ruby:

  1. Creating a namespace, that is, grouping logically related objects together, which also helps avoid name conflicts
  2. Facilitating composition within your application

Ruby, as a programming language, does not support multiple inheritance. Therefore, to keep the code scalable and maintainable in the long run, it is necessary to apply the principle of Composition Over Inheritance. Fortunately, Ruby makes composition easier by offering what is called the Mixing Facility.

Happy dance


Happy dance!

The Mixing Facility is simply a module being included by another module, or even by another class, using keywords like include, prepend, or extend.

Composition vs. Inheritance

Ah, the age-old dilemma for those who program in object-oriented languages and for a paycheck. This debate is present from the earliest stages of learning to the most seasoned seniors. Precisely because it’s so prevalent in our daily work, I think it’s important to revisit the definitions of these two concepts, especially since it’s already explained above why one is more important for Rails. I’m also leaving a link to a well-detailed DevMedia article (in PT-BR) that explains the importance of each and when to use them (spoiler: most of the time, it’s not Inheritance).

Inheritance

Inheritance in programming is defined by the existence of a parent class (also known as a base class or superclass) and a child class (or subclass), and it is considered a fundamental tool for extending and reusing functionalities. In this principle, we focus heavily on the generalization of concepts: similarities between classes are placed in the parent class, while all specific business logic is placed in the child class.

In this concept, there is a strong coupling between classes, as one class depends on the other throughout the system.

Composition

In Composition, we define small behaviors that will exist between classes, which are standardized. As our classes are created and evolve, we compose more complex behaviors using these small units of behavior that have already been designed and tested. Here, the emphasis is on encapsulating logic, which is always a good practice.

Some Legos


Encapsulate your stuff, bro.


🪡 Revisions and Corrections

May 30, 2023 – I corrected some parts of the text that mistakenly stated that modules belong to Rails, when they actually belong to Ruby itself. Thanks to Sérgio Ribeiro for the heads up! 😀


✔ Links consulted

RubyGuides: How to Use Rails Helpers (Complete Guide) – by Jesus Castello

Helper Methods – by Damely Tineo

Modules in Ruby: Part I – by RubyCademy

DevMedia: Herança versus Composição: qual utilizar? – by Higor

Last accessed on April 2, 2023.


📩 A Last Message

Did you like the text? Do you have anything to add? Any constructive criticism? Feedback? Suggestions? Requests? Feel free to contact me via email (oli.pmatt@gmail.com), LinkedIn (/in/oliviamattiazzo) or through the comments section below! I’d be delighted to chat with you! ✨

You can also check the original post (in PT-BR) at my blog: oliviamattiazzo.dev

ko-fi


🪪 Credits

The icons used to illustrate this post came from the following IconFinder users:

. .
Terabox Video Player