The Clean-up Refactor Deleting ".arel_tables"

— 2019-10-02

Sometimes, when composing queries that utilize arel, the queries can start to include a multitude of columns across a couple of tables. This can lead to longer lines due to the repetitive use of .arel_tables[]

Product
  .joins(:sales)
  .where(Sale.arel_table[:ends_on].gt(Time.current).or(Sale.arel_table[:ends_on].eq(nil)))
  .order(Sale.arel_table[:discount_percent])

We can create something that is a little more elegant and makes .arel_table[] feel as if it were a part of the ActiveRecord interface a little more directly. This can be done by creating a class method, #[], on our ApplicationRecord class like so:

# frozen_string_literal: true

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def self.[](column)
    arel_table[column]
  end
end

This allows us to re-write our above code like so:

Product
  .joins(:sales)
  .where(Sale[:ends_on].gt(Time.current).or(Sale[:ends_on].eq(nil)))
  .order(Sale[:discount_percent])

In the projects I’ve worked on, this tiny method adds a lot of value for codebases using complex queries.

What do you think?