activerecord

ruby
module Keysettable
  extend ActiveSupport::Concern

  included do
    scope :keyset_page, ->(after: nil, limit: 20) do
      relation = order(created_at: :asc, id: :asc).limit(limit + 1)

Keyset (Cursor) Pagination for ActiveRecord in Rails

rails activerecord pagination
by codesnips 4 tabs
ruby
class Current < ActiveSupport::CurrentAttributes
  attribute :tenant, :request_id

  def tenant=(tenant)
    super
    Rails.logger.tagged("tenant=#{tenant&.id}") if tenant

Tenant Isolation in Rails with CurrentAttributes and an around_action

rails multi-tenancy current-attributes
by codesnips 4 tabs
ruby
module Cacheable
  extend ActiveSupport::Concern

  def cache_query(prefix, scope, expires_in: 15.minutes)
    key = [prefix, cache_version_token(scope)].join("/")

Targeted Query Caching for Expensive Endpoints

rails activerecord performance
by codesnips 3 tabs
ruby
class CreateAuditLogs < ActiveRecord::Migration[7.1]
  def change
    create_table :audit_logs do |t|
      t.references :auditable, polymorphic: true, null: false
      t.references :user, null: true, foreign_key: true
      t.string :action, null: false

Rails Audit Log for Model Changes Using ActiveRecord Callbacks

rails activerecord callbacks
by codesnips 4 tabs
ruby
class Cart < ApplicationRecord
  has_many :cart_items, dependent: :destroy

  EXPIRY_WINDOW = 2.hours

  scope :active, -> { where(state: :active) }

Expire Stale Shopping Carts With a Rails Scope and a Recurring Reaper Job

rails activerecord background-jobs
by codesnips 3 tabs
ruby
Rails.application.routes.draw do
  resources :articles do
    resources :comments, shallow: true, only: %i[index new create show edit update destroy]
  end

  root "articles#index"

Nested Comments on Articles with Shallow Routing and Scoped Lookups in Rails

rails routing controllers
by codesnips 3 tabs
ruby
class Order < ApplicationRecord
  has_many :line_items, inverse_of: :order, dependent: :destroy

  accepts_nested_attributes_for :line_items,
    allow_destroy: true,
    reject_if: ->(attrs) { attrs["product_id"].blank? && attrs["quantity"].blank? }

Validate Nested Attributes for an Order and Its Line Items in Rails

rails activerecord validations
by codesnips 3 tabs
ruby
class OverdueInvoicesQuery
  def initialize(relation: Invoice.all, as_of: Time.current)
    @relation = relation
    @as_of = as_of
  end

ActiveRecord::Relation as a Boundary (No Arrays)

rails activerecord query-objects
by codesnips 3 tabs
ruby
class AddVersionsToArticles < ActiveRecord::Migration[7.1]
  def change
    add_column :articles, :versions, :jsonb, null: false, default: []
    add_index :articles, :versions, using: :gin
  end
end

Versioning Rails Records with a JSON Snapshot Column and Diff Helper

rails postgres jsonb
by codesnips 3 tabs
ruby
class Order < ApplicationRecord
  include TransactionalEnqueue

  belongs_to :customer
  has_many :line_items, dependent: :destroy

Transaction-Safe After-Commit Hook (Avoid Ghost Jobs)

rails activerecord background-jobs
by codesnips 4 tabs
ruby
class AddSlugToArticles < ActiveRecord::Migration[7.1]
  def change
    add_column :articles, :slug, :string, null: false, default: ""
    add_index :articles, :slug, unique: true

    # Backfill existing rows before the unique index is relied upon in code.

Generate Unique URL Slugs in Rails with before_validation and a friendly Controller Lookup

rails activerecord slugs
by codesnips 3 tabs
ruby
module DomainEvents
  class Registry
    def initialize
      @subscribers = Hash.new { |h, k| h[k] = [] }
    end

Avoid Callback Chains: Use Domain Events (In-App)

rails architecture domain-events
by codesnips 4 tabs