Use the Attributes API to make your Rails models more communicative
ActiveRecord is the powerful object-relational mapper at the heart of Ruby on Rails. By default, it gives you tools to quickly and easily create new database tables and map them to domain models. It follows the ethos of “convention over configuration” that David Heinemeier Hansson coined with the release of Rails. As such, with little application code, you get a powerful, database-backed model that Just Works™.
However, few lines of code do not, necessarily, mean that the lines that are there are easy to understand. Does this model have a
description? How is that
expiryfield encoded, as a Date or a Time? What fields exist on this table, again? These are examples of common questions when working in a Ruby on Rails application.
To alleviate some of these issues, you can use the Attributes API when defining your models to make them more explicit. You can also use richer data types for your fields to ease working with subsets of your models. This article will share the history of the Attributes API, then show some concrete examples of using it.
3 Ways to Make Arel a Joy
Arel, the SQL syntax tree constructor library backing ActiveRecord, allows you to express your SQL queries without the use of fragments. ActiveRecord uses it internally to represent a variety of queries. It does this transparently using the traditional
where(key: value)syntax that we’ve seen since the early days of Rails.
In cases where you only need to write simple query predicates, the traditional syntax is what you should reach for, full stop. However, when you need to write a more complex query like grouped pagination or null-based ordering, I recommend reaching for Arel.
However, because Arel considers itself a “framework framework,” it’s not a truly enjoyable to use out-of-the-box. This article shares three ways to make Arel a joy to use.
Null-based ordering in ActiveRecord
When designing your domain model for an application, the natural solution might end up using a
nilto model the absence of a value. In these cases, you might need to reach for null-based ordering within your database. When you’re writing a Ruby on Rails application, you’re most likely going to use ActiveRecord as the interface to your database. While ActiveRecord supports most queries out-of-the-box, sometimes you have to go off the beaten path.
Null-based ordering is one of those situations. Since ActiveRecord’s ordering works based on simple
key: :directionpairs, it is hard to perform null-based ordering outside of using the built-in behavior of your database. This article outlines two ways you can structure this type of null-based ordering, along with the caveats of using them.
A checklist for reviewing Rails database migrations
Software teams often cite code reviews as a primary means for ensuring quality and reducing bugs in their code. However, without high quality reviews, the efficacy of this practice is questionable. In most places that I’ve worked, a change requires only one code review (either through necessity due to team size or through informal norms). When this is the case, the code review becomes a taxing process where, if you’re not on your game, bugs or maintainability issues can start to leak into production. This means that it often falls to the senior engineers to do code reviews. However, relying entirely on the seniors means that they become a bottleneck in the process. When it comes to “dangerous” changes like Rails database migrations, the bottleneck of relying on a small subset of the team can mean that velocity drops. Or, to keep up velocity, you make code reviews less stringent and quality drops.
In try to “scale myself” for my team, I have started to experiment with checklists for performing code reviews. The first one that I wrote up is a checklist for reviewing Rails database migrations. We run on Heroku, which means that zero-downtime migrations are easy to do, as long as you write your migrations correctly. I intend this checklist to help more junior teammates do as thorough of a job in reviewing as I do. Going forward, I want to make more checklists for doing different types of code reviews, to further scale myself for my team.
Grouped pagination in ActiveRecord
Sometimes, designers will mock-up an extremely usable page that they’ve thought about and tested. Once they’re done and they bring it to you to implement, you look at it and think, “how on Earth can I do that efficiently?” One such case happened at work recently.
We were working on a “command center” of sorts where we show our customers a list of upgrades in various states. The design called for what looked like three different lists of records with each table consisting of records in a state. Since a customer can have potentially dozens of these records, we knew we wanted to paginate the page. The wrinkle in setup was that the pagination should consider the full list of records as the dataset, not each list individually. This caused us to wonder how we can efficiently implement grouped pagination in ActiveRecord.