instance method in_order_of

Ruby on Rails 8.0.4

Since v7.0.10

Available in: v7.0.10 v7.1.6 v7.2.3 v8.0.4 v8.1.2

Signature

in_order_of(column, values, filter: true)

Applies an ORDER BY clause based on a given column, ordered and filtered by a specific set of values.

User.in_order_of(:id, [1, 5, 3])
# SELECT "users".* FROM "users"
#   WHERE "users"."id" IN (1, 5, 3)
#   ORDER BY CASE
#     WHEN "users"."id" = 1 THEN 1
#     WHEN "users"."id" = 5 THEN 2
#     WHEN "users"."id" = 3 THEN 3
#   END ASC

column can point to an enum column; the actual query generated may be different depending on the database adapter and the column definition.

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ]
end

Conversation.in_order_of(:status, [:archived, :active])
# SELECT "conversations".* FROM "conversations"
#   WHERE "conversations"."status" IN (1, 0)
#   ORDER BY CASE
#     WHEN "conversations"."status" = 1 THEN 1
#     WHEN "conversations"."status" = 0 THEN 2
#   END ASC

values can also include nil.

Conversation.in_order_of(:status, [nil, :archived, :active])
# SELECT "conversations".* FROM "conversations"
#   WHERE ("conversations"."status" IN (1, 0) OR "conversations"."status" IS NULL)
#   ORDER BY CASE
#     WHEN "conversations"."status" IS NULL THEN 1
#     WHEN "conversations"."status" = 1 THEN 2
#     WHEN "conversations"."status" = 0 THEN 3
#   END ASC

filter can be set to false to include all results instead of only the ones specified in values.

Conversation.in_order_of(:status, [:archived, :active], filter: false)
# SELECT "conversations".* FROM "conversations"
#   ORDER BY CASE
#     WHEN "conversations"."status" = 1 THEN 1
#     WHEN "conversations"."status" = 0 THEN 2
#     ELSE 3
#   END ASC

Parameters

column req
values req
filter key = true
Source
# File activerecord/lib/active_record/relation/query_methods.rb, line 717
    def in_order_of(column, values, filter: true)
      model.disallow_raw_sql!([column], permit: model.adapter_class.column_name_with_order_matcher)
      return spawn.none! if values.empty?

      references = column_references([column])
      self.references_values |= references unless references.empty?

      values = values.map { |value| model.type_caster.type_cast_for_database(column, value) }
      arel_column = column.is_a?(Arel::Nodes::SqlLiteral) ? column : order_column(column.to_s)

      scope = spawn.order!(build_case_for_value_position(arel_column, values, filter: filter))

      if filter
        where_clause =
          if values.include?(nil)
            arel_column.in(values.compact).or(arel_column.eq(nil))
          else
            arel_column.in(values)
          end

        scope = scope.where!(where_clause)
      end

      scope
    end

Defined in activerecord/lib/active_record/relation/query_methods.rb line 717 · View on GitHub · Improve this page · Find usages on GitHub

Defined in ActiveRecord::QueryMethods

Type at least 2 characters to search.

↑↓ navigate · open · esc close