/ RAILS

Rails 6 ActiveRecord disable enum scopes

Rails 6 ActiveRecord added an option to be able to disable scopes generated by Rails enums by default. These scopes can cause conflict with method names on model or in general Rails application.

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
            }
        end

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

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

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

Similarly it gives scopes like Product.sold_out and Product.archived for the example given above.

ActiveRecord enum instance methods

product = Product.first
product.active?
# true

As we can see, enums provide methods on an instance of model to verify if it belongs to enum value defined.

After Rails 6

Rails ActiveRecord enum supports a new option _scopes that can take a boolean value which represents if we want to generate scopes for the same.

For the same example discussed above,

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

As we can see _scopes: false option is passed to status enum defined over Product model.

Now, if we try to access scopes generated by this enum, we will get a NoMethodError as given below.

Product.active
# NoMethodError: undefined method `active' for #<Class:0x007fc537e236d8>  

Reference: