Rails 6 ActiveRecord negative enum scopes

Rails 6 ActiveRecord added negative scopes for enums on models. This generates negative scopes for enum types defined for a field on a model.

When enums are used in a model in an Rails application, it generates corresponding scopes in order to easily query or find out if record belongs to the particular enum.

Let’s take an example.

        class Product < ApplicationRecord
            enum status: {
                sold_out:   0,
                active:     1,
                archived:   2

Before Rails 6

As we can see, status of the Product can either be active, inactive or archived. When we use it with enums, it generates scopes on ActiveRecord as given below.

ActiveRecord enum scopes on collection

# SELECT "products".* FROM "products" WHERE "products"."status" = $1  [["status", 0]]

# SELECT "products".* FROM "products" WHERE "products"."status" = $1  [["status", 1]]

# SELECT "products".* FROM "products" WHERE "products"."status" = $1  [["status", 2]]

This can be used to get active products with the scope generated by enums defined on the model.

After Rails 6

In addition to scopes defined above, we have access to negative scopes as given below.

# SELECT "products".* FROM "products" WHERE "products"."status" != $1  [["status", 0]]

# SELECT "products".* FROM "products" WHERE "products"."status" != $1  [["status", 1]]

# SELECT "products".* FROM "products" WHERE "products"."status" != $1  [["status", 2]]

As we can see, the scopes generated is a short hand for where.not(column_name: :enum_value).



Akshay Mohite

Hi there! I am a Ruby on Rails & ReactJS Enthusiast, building some cool products at DTree Labs.

Read More