Maquina

Building a Modern
Rails Application

From rails new to production-ready — with authentication, multi-tenancy, and background jobs.

Tools for developers who ship alone

Maquina

Open-source development tools for Ruby on Rails. UI components and generators extracted from production applications — not theoretical exercises.

Production First

Every tool is battle-tested in real apps before it ships. No prototypes.

Standard Rails

ERB partials, Tailwind CSS, Stimulus. No custom DSLs, no magic — just Rails conventions.

One Person Scale

Designed for solo developers. Simple enough for one, powerful enough for production.

maquina.app — Generators, Components, MCP Server, Claude Skills

Every Rails app starts the same way

After rails new, you always end up doing the same setup:

Authentication

Rails 8 gives you login but no signup. You need registration, roles, accounts… every single time.

Operations

Error tracking, job queue dashboard, rate limiting — you set these up manually for every project.

Configuration

Mailer setup, CI scripts, linter config, Procfile, environment variables… the same boilerplate.

UI Components

Forms, tables, cards, alerts — you rebuild the same Tailwind patterns or reach for heavy JS frameworks.

The Maquina ecosystem

Generators

Rails generators that produce standalone code with no runtime dependency. Generate once, own forever. The gem is development-only — remove it after running and everything still works.

$ rails g maquina:app --auth registration

Components

20+ UI components — ERB partials styled with Tailwind CSS 4.0 and Stimulus. Inspired by shadcn/ui but purpose-built for Rails. Zero dependencies beyond Tailwind.

$ rails g maquina_components:install

Rails MCP Server

LLM integration for Rails projects — connect AI tools directly to your codebase context.

Claude Skills

Rails Upgrade, Rails Simplifier, Recuerd0 — specialized AI skills following 37signals patterns.

Available generators

maquina:clave

Passwordless email-code auth. Complete sign-in/sign-up with verification codes, mailer, cleanup job.

maquina:registration

Password-based auth on top of Rails 8. Account model, user roles (admin/member), styled registration flow.

maquina:rack_attack

Request protection. Blocks scanners, throttles abusive IPs, safelists localhost.

maquina:solid_queue

Solid Queue as Active Job backend. Config, application setup, Procfile integration.

maquina:solid_errors

Error tracking dashboard with HTTP auth, engine mounting, optional custom views.

maquina:mission_control

Job queue dashboard with credential-based access and engine mounting.

The orchestrator: maquina:app

One command that runs all generators and sets up your entire application.

$ rails g maquina:app --auth registration

What it configures

  1. Adds gems (brakeman, standard, rails-i18n, etc.)
  2. Creates Procfile, config files, CI scripts
  3. Configures environments (mailer, URLs)
  4. Installs Action Text & Active Storage
  5. Sets up Turbo morphing in layout
  6. Creates HomeController with root route

Sub-generators it runs

  • Your auth choice (clave or registration)
  • maquina:rack_attack
  • maquina:solid_queue
  • maquina:mission_control_jobs
  • maquina:solid_errors
  • maquina_components:install
Hands-on

Let's build an app

A production-ready Rails app with everything you need from day one.

rails new maquina:app db:migrate bin/dev

01 Create the Rails app

$ rails new myapp --css tailwind
$ cd myapp

Rails 8 gives you sensible defaults out of the box:

Included by default

  • SQLite (production-ready with solid adapters)
  • Tailwind CSS via tailwindcss-rails
  • Propshaft asset pipeline
  • Importmap (no Node.js needed)

Solid trifecta

  • Solid Queue for background jobs
  • Solid Cache for caching
  • Solid Cable for WebSockets
  • Kamal for deployment

You can already run bin/dev and visit http://localhost:3000

02 Add Maquina generators

$ bundle add maquina_generators --group development

Then run the app generator with your chosen authentication:

$ rails generate maquina:app --auth registration

This is a development-only gem. Generated code lives entirely in your app — no runtime dependency. Delete the gem after running.

Auth options

--auth none — no authentication (default)
--auth clave — passwordless email-code authentication
--auth registration — password-based with Account + roles

02 What the generator does

  1. Adds gems (brakeman, standard, rails-i18n, maquina_components)
  2. Creates Procfile.dev and config files
  3. Creates bin/setup and bin/ci scripts
  4. Configures environments (letter_opener, mailer)
  5. Installs Action Text & Active Storage
  6. Runs maquina:registration auth generator
  7. Runs rack_attack, solid_queue, mission_control, solid_errors
  8. Creates HomeController with root route

Finish setup

$ bin/rails generate solid_errors:install
# decline the initializer overwrite

$ bin/rails db:migrate

$ bin/rails credentials:edit
# set backstage username/password

$ bin/dev

03 The registration generator

Builds on top of Rails 8's generate authentication, which gives you login but no signup.

Rails auth creates

  • User model with has_secure_password
  • Session model
  • Current model
  • Authentication concern
  • SessionsController (login/logout)
  • PasswordsController (reset)

Registration adds

  • Account model (tenant)
  • User → belongs_to :account + roles
  • Current → Current.account
  • RegistrationsController (signup)
  • Tailwind-styled views
  • English + Spanish translations

03 Key generated files

Account model

class Account < ApplicationRecord
  has_many :users, dependent: :destroy

  validates :name, presence: true
end

User model

class User < ApplicationRecord
  has_secure_password
  has_many :sessions, dependent: :destroy
  belongs_to :account

  validates :name, presence: true

  enum :role,
    {member: "member", admin: "admin"},
    default: "member"
end

Current model

class Current < ActiveSupport::CurrentAttributes
  attribute :session
  delegate :user, to: :session, allow_nil: true
  delegate :account, to: :user, allow_nil: true
end

Access anywhere

# In any controller or view:
Current.user     # logged-in user
Current.account  # user's account
Current.user.admin? # role check

03 Registration flow

Creates Account + User (as admin) in a single transaction:

class RegistrationsController < ApplicationController
  allow_unauthenticated_access
  rate_limit to: 10, within: 3.minutes, only: :create

  def create
    ActiveRecord::Base.transaction do
      account = Account.create!(name: params[:account_name])
      user = account.users.create!(
        name: params[:name],
        email_address: params[:email_address],
        password: params[:password],
        role: :admin
      )
    end

    start_new_session_for user
    redirect_to root_path
  end
end

The first user who creates an account automatically becomes its admin.

03 Authentication flow

Public  No login required

/registrations/new /session/new /passwords/new

Protected  Everything else

The Authentication concern is included in ApplicationController.
Every controller requires login by default. Only controllers with allow_unauthenticated_access are public.

Ops dashboards  HTTP Basic Auth

/admin/solid_errors /admin/mission_control_jobs

Separate from app auth. Credentials from rails credentials:edit

04 Your first resource

$ bin/rails generate scaffold Project name:string description:text account:references
$ bin/rails db:migrate

Add the association

# app/models/account.rb
class Account < ApplicationRecord
  has_many :users, dependent: :destroy
  has_many :projects, dependent: :destroy

  validates :name, presence: true
end

Scope the model

# app/models/project.rb
class Project < ApplicationRecord
  belongs_to :account

  validates :name, presence: true
end

04 Multi-tenancy pattern

Always query through Current.account — users never see data from other accounts.

class ProjectsController < ApplicationController
  def index
    @projects = Current.account.projects
  end

  def create
    @project = Current.account.projects.build(project_params)

    if @project.save
      redirect_to @project
    else
      render :new, status: :unprocessable_entity
    end
  end

  private

  def set_project
    @project = Current.account.projects.find(params[:id])
    # raises RecordNotFound if project belongs to another account
  end
end

05 Role-based authorization

Use the role enum to restrict actions by user role.

class ProjectsController < ApplicationController
  before_action :require_admin, only: [:destroy]

  # ...

  private

  def require_admin
    unless Current.user.admin?
      redirect_to projects_path,
        alert: t("flash.general.forbidden")
    end
  end
end

admin

First user created with an account. Full access to all actions.

member

Default role for subsequent users. Restricted from destructive actions.

06 The full picture

app/
  controllers/
    concerns/
      authentication.rb session mgmt
    sessions_controller.rb login
    passwords_controller.rb reset
    registrations_controller.rb signup
    home_controller.rb root
    projects_controller.rb yours
  models/
    account.rb tenant
    user.rb roles + auth
    current.rb request context
    session.rb browser sessions
    project.rb yours

Security defaults

  • Rate limiting on registration and login
  • Rack Attack blocks scanners and bots
  • All controllers require auth by default
  • Account scoping prevents data leaks

Ops dashboards

  • /admin/solid_errors — error tracking
  • /admin/mission_control_jobs — job queue

Five commands to
production-ready

$ rails new myapp --css tailwind
$ bundle add maquina_generators -g development
$ rails g maquina:app --auth registration
$ bin/rails db:migrate
$ bin/dev

Auth, multi-tenancy, roles, jobs, error tracking, UI components, security — all generated, all yours.

maquina.app

Thank you

Mario Alberto Chávez

Rails architect & AI toolmaker — Colima, México

Open source — all tools available at maquina.app