ActiveRecord Tricks

Episode #127 by Teacher's Avatar David Kimura

Summary

In this episode, we look at what would seemingly be simple queries, but are more complex once you start looking into them. Using built in ActiveRecord functions, we can make the queries readable and easy to work with.
rails activerecord 13:21

Resources

Download Source Code

Summary

# user.rb
class User < ApplicationRecord
  belongs_to :status
  has_many :messages, dependent: :destroy
  scope :active, -> { joins(:status).merge(Status.active) }
  scope :unread_messages, -> { joins(:messages).merge(Message.unread) }
  default_scope { includes(:messages).unread_messages }
end

# status.rb
class Status < ApplicationRecord
  has_many :users
  scope :active, -> { where(active: true) }
  # def self.active
  #   where(active: true)
  # end
end

# message.rb
class Message < ApplicationRecord
  belongs_to :user
  scope :unread, -> { where(read: false)}
  scope :read, -> { where(read: true)}
end

# Terminal
rails db:create db:migrate db:seed
rails c

# rails console
User.count
Status.count
Message.count

reload!

active_statuses = Status.where(active: true).pluck(:id)
active_users = User.where(status_id: active_statuses)
active_users = User.joins(:status).where(statuses: { active: true })

Status.active
Status.active.pluck(:id)
User.joins(:status).where(statuses: { id: Status.active.pluck(:id) })
User.joins(:status).merge(Status.active)

user = User.first
user.messages.pluck(:read)
user.messages.where(read: false)
user.messages.unread

User.active.joins(:messages).merge(Message.read)
User.active.unread_messages

User.active.scoping do
  User.last
end