Part 6 · 1 chapters · ~8 min

Rails End to End

Generating an app, models, migrations and validations, associations, controllers and strong parameters, JSON APIs, authentication (Rails 8 generator, has_secure_password), Active Job with Solid Queue or Sidekiq, Hotwire (Turbo and Stimulus), Action Cable, Active Storage, and credentials.

7

An app in Rails

code
rails new ledger --database=postgresql && cd ledger
bin/rails generate model Account owner:references currency:string balance_kobo:bigint
bin/rails generate authentication            # Rails 8: sessions, password resets, has_secure_password

class Account < ApplicationRecord
  belongs_to :owner, class_name: "User"
  has_many :postings
  validates :currency, inclusion: { in: %w[NGN USD KES] }
  validates :balance_kobo, numericality: { greater_than_or_equal_to: 0 }
end

class TransfersController < ApplicationController
  def create
    transfer = Transfers::Create.call(owner: Current.user, params: transfer_params, idempotency_key: request.headers["Idempotency-Key"])
    render json: transfer, status: :created
  rescue Ledger::InsufficientFunds => e
    render json: { type: "insufficient_funds", detail: e.message }, status: :unprocessable_entity
  end
  private
  def transfer_params = params.require(:transfer).permit(:amount_kobo, :to)
end

class SendReceiptJob < ApplicationJob          # Active Job; Solid Queue by default in Rails 8
  queue_as :default
  retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 8
  def perform(transfer_id) = Receipts.deliver(Transfer.find(transfer_id))
end
A RAILS REQUEST
Puma → Rack middleware → router → controller → model → view
Pumathreads + workersRack middleware~25 layersrouterroutes.rbcontrollerfilters, strong paramsActive RecordSQLview / JSONJbuilder, Turbo
swipe the figure sideways, or tap expand for full screen
1/5
Puma and Rack
Puma calls the Rails app through Rack: a single call(env) interface every Ruby web framework shares. Rails' stack of Rack middleware handles sessions, cookies, CSRF, logging and exceptions.
Rack: call(env) → [status, headers, body]bin/rails middleware lists the stack