In Ruby By Ziemek June 01, 2016 Ziemek

Organizing Ruby on Rails Models

The Challenge

A few years ago, I remember trying to get developers to work with a particular style when working with models. Placing Class methods before instance methods, making sure that constants appear that the top and so forth.

I would discuss these structures with other developers in our team and write beautiful documentation to show what the structure of a particular model class should be. I would send it around to the list of developers and what happened? No one used the documentation. No one bothered. Perhaps it was the stress level at the time. I eventually gave up and stuck with the messy approach that we were use to.

Fast forward a few years into my career and I end up meeting a developer by the name of Hesham from an agency in Toronto, The Working Group.

He introduces this simple structure, for the models in our app:


class User < ActiveRecord::Base

  # == Constants ============================================================

  # == Attributes ===========================================================

  # == Extensions ===========================================================

  # == Relationships ========================================================

  # == Validations ==========================================================

  # == Scopes ===============================================================

  # == Callbacks ============================================================

  # == Class Methods ========================================================

  # == Instance Methods =====================================================

end

The greatness in simplicity

The structure is simple and easy to follow. Simply place the appropriate code below the comment heading.

Surprisingly, it caught on. Developers within our team started to adopt this style. Not only that, the code began to feel more readable and it became easier to work with. Scopes were no longer listed in odd places. Class methods were always listed in the same spot and not intermixed with instance methods.

This simple change, introduced a level of organization to our code that was quickly adopted and used. And it’s just comments within the code base!

Why this worked

This worked well because the documentation was not an external document that each developer needed to look up. This might seem insignificant, why would it take so long to find a document that everyone already has booked marked. Simple, it doesn’t break context. You don’t need to switch applications, you don’t even need to look anywhere else. It’s all right there.

Everyone who used it, saw immediate value. They were able to find the code much quicker and were able to see the section where their code should exist.
From a maintainability standpoint, there is no question where the code should go. It became pretty obvious. It’s right there in the comment and the guessing game is over.

Closing thoughts

The above code is used for model specifically. I actually not used them in any other place. I personally enjoy this style.
Here is the snippet to added to your sublime text or atom.

Resources

Snippets are great if you need a particular structure of code over and over again. The following only works when you are in a ruby class. (Feel free to modify if this does not suit your needs.)

Sublime Text:

  1. Go to tools -> Developer -> New Snippet

    2 . Replace with the following code:

    
    <snippet>
      <content><![CDATA[
    # == Constants ============================================================
    
    # == Attributes ===========================================================
    
    # == Extensions ===========================================================
    
    # == Relationships ========================================================
    
    # == Validations ==========================================================
    
    # == Scopes ===============================================================
    
    # == Callbacks ============================================================
    
    # == Class Methods ========================================================
    
    # == Instance Methods =====================================================
    
    ]]></content>
      <!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
      <tabTrigger>#==</tabTrigger>
      <!-- Optional: Set a scope to limit where the snippet will trigger -->
      <scope>source.ruby</scope>
    </snippet>
    
    
  2. Open a model type: "#==" [Tab]

Atom

  1. Open Atom -> Snippets ...

  2. Place the code at the bottom of the file.

    
    
    '.source.ruby':
      'Model class structure':
        'prefix': '#=='
        'body': '''
          # == Constants ============================================================
    
          # == Attributes ===========================================================
    
          # == Extensions ===========================================================
    
          # == Relationships ========================================================
    
          # == Validations ==========================================================
    
          # == Scopes ===============================================================
    
          # == Callbacks ============================================================
    
          # == Class Methods ========================================================
    
          # == Instance Methods =====================================================
    '''
    
  3. Go to any ruby file, type "#==" [tab]