<h1>Catalog</h1>
<%= turbo_frame_tag "products" do %>
<div class="product-grid" data-controller="frame">
<% @products.each do |product| %>
<%= render "products/card", product: product %>
<%= tag.div id: dom_id(comment), class: "comment", data: { controller: "comment" } do %>
<div class="comment__body">
<%= comment.body %>
</div>
<footer class="comment__meta">
class User < ApplicationRecord
has_many :posts, foreign_key: :author_id
validates :email, presence: true,
uniqueness: { case_sensitive: false },
format: { with: URI::MailTo::EMAIL_REGEXP }
cleanup_expired_sessions:
cron: '0 2 * * *' # Daily at 2 AM
class: CleanupExpiredSessionsWorker
queue: low
description: Remove expired sessions from Redis
class WizardsController < ApplicationController
STEPS = %w[account profile confirm].freeze
before_action :set_step
def show
<%= turbo_stream.prepend 'items' do %>
<%= render @item %>
<% end %>
<turbo-stream action="reset_form" target="new_item_form"></turbo-stream>
module KeysetPaginatable
extend ActiveSupport::Concern
class_methods do
def keyset_page(cursor: nil, limit: 20, direction: :desc)
limit = limit.to_i.clamp(1, 100)
Rails.application.config.middleware.insert_before(
Rack::Runtime,
Rack::Timeout,
service_timeout: 15 # 15 seconds
)
class LeaderboardCache
TOP_KEY = "leaderboard:top".freeze
STATS_KEY = "leaderboard:stats".freeze
def top_players
Rails.cache.fetch(TOP_KEY, expires_in: 5.minutes, race_condition_ttl: 15.seconds) do
class CreateWebhookEvents < ActiveRecord::Migration[7.1]
def change
create_table :webhook_events do |t|
t.string :event_id, null: false
t.string :source, null: false, default: "stripe"
t.string :event_type, null: false
module MyApp
class Application < Rails::Application
config.load_defaults 6.1
# Enable response compression
config.middleware.use Rack::Deflater
class SyncContactJob < ApplicationJob
queue_as :external
BACKOFF = ->(executions) do
(2**executions) + rand(0.0..1.0) # exponential + jitter, in seconds
end