rails

ruby
class SlugValidator < ActiveModel::Validator
  SLUG_REGEX = /\A[a-z0-9]+(?:-[a-z0-9]+)*\z/

  def validate(record)
    slug = record.send(options[:attribute] || :slug)

Rails validators for custom business logic

rails validations activemodel
by Maya Patel 2 tabs
erb
<nav class="site-nav" data-controller="preload">
  <ul>
    <li>
      <%= link_to "Dashboard", dashboard_path,
            class: "nav-link",
            data: { turbo_preload: true } %>

Speed up perceived performance with Turbo preload links

rails hotwire turbo
by codesnips 3 tabs
ruby
class CreateTopSellersMv < ActiveRecord::Migration[7.0]
  def up
    execute <<~SQL
      CREATE MATERIALIZED VIEW top_sellers AS
        SELECT p.id            AS product_id,
               p.name          AS product_name,

Cache-Friendly “Top N” with Materialized View Refresh

rails postgres performance
by codesnips 4 tabs
erb
<div class="layout">
  <ul class="product-list">
    <% @products.each do |product| %>
      <li class="product-row">
        <%= link_to product.name,
              product_path(product),

Turbo Frames: “details” panel that lazy-loads on click

rails turbo hotwire
by codesnips 4 tabs
ruby
class PostSerializer < ActiveModel::Serializer
  attributes :id, :title, :excerpt, :body, :published_at, :views, :likes_count, :comments_count

  attribute :can_edit, if: :current_user_can_edit?

  belongs_to :author, serializer: UserSummarySerializer

Serializers with ActiveModel::Serializers

rails api serialization
by Alex Kumar 2 tabs
ruby
class CreateDeadJobs < ActiveRecord::Migration[7.1]
  def change
    create_table :dead_jobs do |t|
      t.string  :jid, null: false
      t.string  :queue, null: false
      t.string  :klass, null: false

Background Job Dead Letter Queue (DLQ) Table

rails reliability background-jobs
by codesnips 4 tabs
ruby
class PostsController < ApplicationController
  def index
    posts = Post.for_feed.page(params[:page]).per(25)

    render json: {
      data: posts.map { |post| PostSerializer.new(post).as_json },

N+1 Proof Serialization with preloaded associations

rails activerecord performance
by codesnips 3 tabs
ruby
class ReportQuery
  SQL = <<~SQL.freeze
    SELECT date_trunc('day', events.created_at) AS day,
           count(*) AS total,
           count(*) FILTER (WHERE events.kind = 'purchase') AS purchases
    FROM events

Safe Raw SQL with exec_query + Binds

rails activerecord sql
by codesnips 2 tabs
ruby
class Comment < ApplicationRecord
  belongs_to :post
  belongs_to :author, class_name: "User"

  has_rich_text :body

Action Text comment form that works inside a Turbo Frame

rails hotwire turbo
by codesnips 3 tabs
ruby
class ProductsController < ApplicationController
  before_action :set_product, only: %i[edit update]

  def index
    @products = Product.order(:name)
  end

Inline edit a table row with Turbo Frames

rails hotwire turbo
by codesnips 4 tabs
ruby
module Paginatable
  extend ActiveSupport::Concern

  MAX_PER_PAGE = 100
  DEFAULT_PER_PAGE = 25

API Pagination Headers (Link + Total)

rails pagination rest-api
by codesnips 3 tabs
ruby
cookies.encrypted[:trusted_device] = {
  value: { user_id: current_user.id, fingerprint: device_fingerprint }.to_json,
  expires: 30.days.from_now,
  httponly: true,
  secure: Rails.env.production?,
  same_site: :strict,

Signed and encrypted Rails cookies for tamper resistant state

rails cookies encryption
by Kai Nakamura 1 tab