1 min read

Classes vs Modules for Obese Models

The concept of Thin controllers and fat models is preached heavily to individuals who are just picking up Rails. In my opinion the same concern should be extended to models as well. Quite often is it the case that models in a Rails app tend to get really large(1000 loc+ in same cases!). This results in a coding nightmare.

In order to have cleaner code, this issue can be addressed in multiple ways. Two of which(for a monolithic architecture) are using:


A common practice is to extract a set of related methods from the model and move them to a separate module. These modules then serve as mixins to the actual model.

class User < ActiveRecord::Base
  include Billing
  include RegistrationMethods
  include Subscription
  include Socials

The issue that I feel exists with this approach is that inferencing where a certain method is coming from tends to be quite unintuitive. The actual developer who made the modules might have no issues, however, scenarios will always exist where the rest of the dev-team will need to execute a grep command to figure out where a method is being defined.

Classes Ftw!

A better approach would be to break down the functionality into smaller classes that have  actual meaning.

class Subscription
  def initialize(user)
    @user = user

  def subscribe!

  def unsubscribe!

By breaking down the functionality and collecting them into logical entities(OOP) you gain the following advantages.

No More Grep Driven Development. Reading the code becomes very intuitive. I know exactly where to look in my code base to figure out the code.

The interfaces are very clean and well-defined.

Classes can be completely independent from Rails. TDD becomes uber fast as we do not need to require the evil spec_helper(i.e. Rails).(Thank you Gary of DAS for this. You've helped me a lot. )

Ending Notes

It is important to note that I'm in no way saying that modules are completely useless. Though I do feel that they are overused and that Object Oriented Design is often times overlooked while working in the Rails environment.