Using Scopes and Custom Queries with Enums

Rails automatically generates scopes for querying enums, but in advanced scenarios, you might need custom queries to refine results.

1. Default Enum Scopes (Generated by Rails)

As discussed in earlier chapters, Rails automatically creates scopes for enums:

class User < ApplicationRecord
  enum :status, { active: 0, inactive: 1, banned: 2 }
end

You can use these scopes to filter users:

User.active   # Fetch all active users
User.banned   # Fetch all banned users

However, these default scopes might not be enough in complex applications.

2. Creating Custom Enum Scopes

Sometimes, we need custom scopes that combine multiple enum values or include additional logic.

Example: Finding all non-banned users

class User < ApplicationRecord
  enum :status, { active: 0, inactive: 1, banned: 2 }

  scope :non_banned, -> { where.not(status: :banned) }
end

Now, you can easily fetch all users who are not banned:

User.non_banned

Example: Combining Multiple Enum Scopes

Let’s say we want to fetch both active and inactive users together.

class User < ApplicationRecord
  enum :status, { active: 0, inactive: 1, banned: 2 }

  scope :active_or_inactive, -> { where(status: [:active, :inactive]) }
end

Now, calling:

User.active_or_inactive

will return all users except banned ones.

3. Using Enums in Raw SQL Queries

If you’re working with raw SQL, you need to query using integer values.

User.where("status = ?", User.statuses[:active])

This ensures compatibility with Rails enums while using raw SQL.