ActiveRecord::QueryMethods in_order_of
Chapters7
Introduce the problem of ordering tasks by status and the motivation for customizing order beyond the default.
Colin shows how ActiveRecord::QueryMethods'in_order_of' lets you order records by a fixed status sequence with a simple symbol array.
Summary
Colin from GoRails introduces ActiveRecord's in_order_of method as a clean alternative to manual Ruby sorting or SQL CASE statements. He starts with a simple tasks app and demonstrates the default ordering by ID, then walks through pure Ruby approaches (hash-based priority and a sort_by block) and a long-winded SQL CASE alternative, pointing out the downsides of each. The core of the lesson is that in_order_of makes this common UI need trivial: specify the column (status) and an array of desired values (urgent, in_progress, pending, done) and let Rails handle the rest. He also notes that in_order_of works nicely with enum columns and even supports nil values, which can be placed at the beginning or end as needed. Colin further shows you can switch the order quickly by reordering the array, such as moving done to the top. The video ends with a quick recap: if you’re not aware of in_order_of, you’ll likely implement more verbose solutions—this method is simple, expressive, and exactly what you want for deterministic, UI-friendly sorting by a fixed sequence.
Key Takeaways
- Use ActiveRecord::Relation#in_order_of to sort by a column (e.g., :status) with a fixed value sequence (e.g., [:urgent, :in_progress, :pending, :done]).
- The method accepts an array of symbols representing the desired order, making it easy to reorder only by changing the array.
- in_order_of works with enum columns and supports nil values, which you can place at the end or beginning of the sequence.
- You can toggle which records appear by adding a false-flag filter on the method to include all results, not just those in the specified list.
- Reordering UI (e.g., moving :done to the top) is as simple as changing the array and reloading, without altering model logic.
- This approach avoids verbose SQL CASE statements or custom Ruby sort blocks and keeps your code concise and readable.
Who Is This For?
Rails developers who want a simple, maintainable way to order records by a fixed status sequence (especially when using enums). It’s ideal for those who previously used Ruby sort_by or SQL CASE and want a cleaner built-in solution.
Notable Quotes
"So you can just call task.in_order_of(:status, [:urgent, :in_progress, :pending, :done]) and Rails will handle the rest."
— Colin introduces the core syntax of in_order_of with a status column and a fixed value array.
"If something didn't have a status, you could add that in there and say, OK, if something doesn't have a status, put that last in the array."
—Colin explains handling nil values with in_order_of.
"One thing that's cool to note is that you can point the column to an enum column and it works fine."
—Highlighting compatibility with enums.
"If you want to show done first, you can delete and reorder the array, save, and refresh."
—Demonstrates the ease of reordering by changing the array.
"Really short and easy to use, but if you don’t know it exists, you’ll end up writing other solutions."
—Colin emphasizes the practicality and discoverability of in_order_of.
Questions This Video Answers
- How does ActiveRecord in_order_of differ from a custom Ruby sort?
- Can I use in_order_of with enum columns in Rails?
- What are best practices for ordering nil values with in_order_of in Rails?
- How to reorder UI elements by changing the in_order_of array in Rails?
Full Transcript
What's up everybody? Colin here at Dorails. Welcome back to another lesson. In this one, we're going to take a look at the in order of method from active record. But to start with, we're going to look at this tasks uh app that we have here. So, pretty standard little thing here. Uh some tasks, they have a title, and they have a status. Right? Right now everything's kind of, you know, just in order of by, you know, hopefully ID here. I think I'm just doing like tasks.all. Yeah. So tasks at tasks equal task.all. So we're just getting kind of this default order in here.
But what if we wanted to put them in a certain order based upon their status? Uh, you know, maybe show all the urgent ones together, then the in progress, and then pending and done if we wanted to show them in that certain order. Uh, we could do that. Uh, we could do that a few ways. one we could try like a pure Ruby approach which could maybe look something like this. We say like priority and then let's make this a hash. If we were to say like urgent uh that would be zero. We do in progress be one.
Depending that would be two. And then of course done would be three here. Oops. Okay. So, we could set, you know, a hash mapping uh these priority levels or statuses to uh these integers here. And then we could come down here and say task uh task.alls sort by. And then inside our block here, we could say uh priority and say it. Okay. So, we can save that. And let's go back to our browser and refresh. Uh let's see. We got a syntax error. Oh, that's because uh I have a space here. All right, let's fix that.
Now, let's refresh. Okay, and we see that that works, right? Uh everything is grouped in that order that we want there. Uh but I will say it's kind of a pain having to like write this hash out yourself and then go through and do the sort by call here. Uh this this part really isn't so big of a deal, but having to write this out is kind of a bummer. Alternatively, we could do something like this here and kind of get down into uh Abra land here. Uh let's see if we can Yeah. get this all nice and formatted properly here.
So, we can do something like this. Uh, task.order aril.sql and then write this case statement in here for all these statuses. If we go back to a browser and refresh, we see we get another error and that is because we need our at tasks variable still. So, let's add that back in and let's go refresh now. Okay. And we see again that uh that also works. But again, uh, having to write something like this is also kind of a bummer. Now, you could probably do some sort of integer position column here to help with this or maybe like an enum thing, but let's go ahead and delete this out of here real quick.
Uh, because one thing that uh, we could actually do that's even better and a lot easier is use the in order of uh, method here from active record. So, you can see here we can just call, you know, task.inorder in order of pass it the name of the column that we want to order by as a symbol and then we pass in an array of the values here. So let's give this a try and see if this gets us what we want here. So let's say at tasks oop equals task in order of and then we need uh status as the column to sort by and then we need our array of symbols here.
So we can do urgent uh in progress. Uh I think pending was next and then done. Okay. So let's go ahead and save that and flip back to our browser here and go to our app and refresh. And now indeed we see that all of those are ordered properly. And if we want to change any order uh for example if we wanted to show done first for example you know we can simply come over here we can delete that and then go over here and add it in the front. Okay let's save that and come over here and refresh and now we see done is sorted now to the top and then everything else falls in order there.
Now one thing that's cool in here to note is that column can point to an enum column. So if you are using an enum column, uh you can totally go ahead and use this with that. Also, uh values can be nil, right? So if something didn't have a status, you could add that in there and say, okay, if something doesn't have a status, if it's new, we could put that last in the array and show those last or first or wherever you want to put them. Additionally, you can set this filter option uh to be false here so that it includes uh all the results instead of just the ones uh that are specified in your list of values that you pass to the method here.
So that's it. Uh that one's really short, really easy to use, but if you don't know it exists, you can't use it and you'll be writing one of those other solutions most likely uh in order to get your desired result. But in order of is really simple, really nice to write and I think it's a great option for doing these sorts of things. So with that, we'll end this one here. And until next time, take care.
Get daily recaps from
GoRails
AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.



