Since belongs_to relation is one of the most common association in each Rails application I bet that you deal with it many times in your application. Let’s say that we have two models: Job and Category- one job belongs to one category and category can have many jobs, simple as that.

Category model has published:boolean attribute which determines if we can show jobs for given category. Our goal is to create a query that would return only jobs assigned to published categories.

Want to receive useful tips, information about new Ruby gems and articles on a daily basis? Make sure you follow me and say hello!

Standard way

Usually we would use something like this:

Job.joins(:category).where(categries: { published: true })

What is wrong with the above example? Nothing, but let’s focus on logic isolation. When we are operating on Job model we shouldn’t care about conditions that we have to meet in order to fetch only published categories - it’s Category model related logic so let’s move it there.

Want to receive useful tips, information about new Ruby gems and articles on a daily basis? Make sure you follow me and say hello!

Logic isolation

class Category < ActiveRecord::Base
 has_many :jobs

  def self.publishable
    where(published: true)

You can use scope instead of class method. I decided to go for the class method as it’s clear to me. Let’s take a look at the Job model now:

class Job < ActiveRecord::Base
  belongs_to :category

  def self.publishable

so we can now call



You are probably wondering why the second solution is better when there is a lot more code to maintain. Here is why:

  1. Logic is isolated. Category related stuff is in Category model, the same for job-related stuff. Your teammates can just call Job.publishable without digging into logic and wondering what query they should exactly use
  2. Imagine that you have the first version of the query, Job.joins(:category).where(categries: {published: true}), in many places of the app. What do you do when to determine if the category is published you have to check more conditions? You have to find all places where you used it - poorly. But when you use the second version all you need to do is to change on method. You didn’t change anything else.
  3. It’s just more readable for human beings - it’s very important when you have junior developers in your team
  4. You can use Category.published everywhere with any model associated with Category
Want to become a better Rails developer?
Download for free the Introduction Rails patterns book and dive into the world of refactoring and easy-testable Ruby code today.
Join over 1,000 developers already subscribed to my newsletter and download the book. You can unsubscribe anytime:

Subscribe and get the book!