ruby

erb
<%# private stream: turbo signs the serialized record name %>
<%= turbo_stream_from current_user %>

<section class="notifications">
  <h1>Notifications</h1>

Turbo Streams + authorization: signed per-user stream name

rails turbo hotwire
by codesnips 3 tabs
erb
<h1>Products</h1>

<%= form_with url: products_path, method: :get,
              data: { turbo_frame: "products_list", turbo_action: "advance" } do |f| %>
  <div class="filters">
    <%= f.text_field :q, value: params[:q], placeholder: "Search products" %>

Frame navigation that targets a specific frame via form_with

rails hotwire turbo
by codesnips 3 tabs
ruby
event_id = request.headers.fetch('X-Event-Id')
timestamp = request.headers.fetch('X-Signature-Timestamp').to_i

raise ActionController::BadRequest, 'stale request' if Time.now.to_i - timestamp > 300
raise ActionController::BadRequest, 'replay detected' if WebhookEvent.exists?(external_id: event_id)

Secure webhook endpoint design with replay protection

webhooks replay-protection hmac
by Kai Nakamura 1 tab
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
raw_token = SecureRandom.urlsafe_base64(32)
token_digest = Digest::SHA256.hexdigest(raw_token)

PasswordReset.create!(
  user: user,
  token_digest: token_digest,

Secure random token generation for sessions and recovery flows

randomness tokens authentication
by Kai Nakamura 1 tab
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