Ruby on Rails: Sort Array Records By Enum Value

icelandcheng
3 min readDec 31, 2020

Sometimes we might need to order records by their attribute value. If using Ruby on Rails Active Record, we could apply Active Record Query Methods: order to order model records by some of their attribute value. For example, if we have a product order model in our shopping website Ruby on Rails project and the model data is like the below table, when those data need to sort by the shipment mode value, we could simply use the order method to achieve that.

we could simply pass 1 param which the column we want records to be sorted by to the order method, and the code would like

Order.all.order(:shipment_mode)

order method would sort record in ascending in default, if we want to sort record in descending, order method also could accept desc params.

Order.all.order(shipment_mode: :desc)

Applying order method in code to sort the order records which status are shipping by shipment mode, and in the result(below picture), we could see that truck records show first because the shipment mode has enum value: truck: 1, sea: 2, air: 3.

Order method is useful when sorting ActiveRecord::Relation data, but if the data is simply an Array, then the order method couldn’t work anymore. Here is an example: we use the Active Record Query Methods: select (which would return an Array)to filter the product order record which address includes ‘New York’ , and use order method to sort the select result by shipment mode. It would show an error when applying order method to the select result. The error says order is not a defined method for Array.

But we still need to sort the select result, then there is another method call sort_by which is belong to Ruby Enumerable class that we could apply to sort Array data, so we could apply sort_by to in this case. The result(below picture) looks fine and there is no more error, but there is still something wrong. It looks like the select result records didn’t order ascending by the shipment mode value, and it is only sorted by the shipment mode enum name alphabetically.

If we want the select result sort by shipment mode value, we need to write a method which could get shipment mode enum value in Order model and using this method when applying sort_by . In this example we call the method numeric_shipment_mode_value and the code of the method is like below.

class Order < ApplicationRecord
include ::EnumValueConcern
enum shipment_mode: {
truck: 1,
sea: 2,
air: 3
}, _prefix: true
def numeric_shipment_mode_value
self.class.shipment_modes[shipment_mode]
end

end

When we apply the sort_by method to select result with numeric_shipment_mode_value, the select result records order in what we expect, and they really order by shipment mode value.

Reference:

Active Record Query Methods: order

Active Record Query Methods: select

Ruby::Enumerable method: sort_by

--

--

icelandcheng

Programming Skill learner and Sharer | Ruby on Rails | Golang | Vue.js | Web Map API