Skip to content

Instantly share code, notes, and snippets.

@danilovelozo
Last active January 17, 2021 14:21
Show Gist options
  • Save danilovelozo/5f6395cd3886e707d6ea99e39db7d388 to your computer and use it in GitHub Desktop.
Save danilovelozo/5f6395cd3886e707d6ea99e39db7d388 to your computer and use it in GitHub Desktop.
Rails ActiveRecord Scopes
# app/models/equipment.rb
class Equipment < ApplicationRecord
has_many :requests
has_many :customers, through: :requests
validates :brand, presence: true
validates :model, presence: true
validates :equipment_type, presence: true
validates :serial_no, presence: true
validates :accessories, presence: true
# Default Scope
default_scope {order("updated_at desc")}
default_scope {where("available = ?", true)}
# Named Scope
scope :not_available, -> { where("available = ?", false)}
scope :available, -> {where("available = ?", true)}
# Named Scope with Arguments
scope :not_available, ->(bool) {where("available = ?", bool)}
# Chaining Scopes
scope :available_and_created, -> {available.order(:created_at)}
# Scope with Conditional
scope :available, -> (bool){where("available = ?", bool) if bool.present? }
# Calling multiple scopes in a class method scope
def self.chaining(multiple_method)
multiple_method.inject(self, :send)
end
end
# Using Named Scope
# equip = Equipment.all
# equip.not_available
# Using Unscoped
# equip = Equipment.first
# equip unscoped
# Using Chaining Scope
# Equipment.brand.is_available
# Using multiple scopes in a class method Scope
# Equipment.chaining(["scope_one", "scope_two"])
# app/controllers/equipment_controller.rb
class EquipmentsController < ApplicationController
def index
@equip = Equipment.is_available
render json: @equip, status: 200
end
# Or
def index
@equips = Equipment.all
render json: @equips, status: 200
end
def availability
@equip = Equipment.is_available
render json: @equip, status: 200
end
# Or
def index
if params[:equipment]
args = params[:equipment][:multiple_method]
@equip = Equipment.chaining(args)
else
@equip = Equipment.all
end
end
end

Scoping allows us to make use of commonly-used queries which can be referenced as method calls on the association objects or models,

The general expectation is that all scope bodies should return an ActiveRecord::Relation or nil. As a result of this, it makes it easy to call other ActiveRecord methods on it. Simply put, a scope is just a custom chain of active record methods. They are sets of pre-defined queries that can be chained to build other complex Queries.

Default Scopes vs Named Scopes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment