supabase-rb-rb
Generators

supabase:install

The main supabase-rails generator — what it writes, what it patches, the options it accepts, and what to do next.

bin/rails generate supabase:install is the one-shot setup generator for supabase-rails. It scaffolds the host-app glue for :web mode — an Authentication concern, five thin controller subclasses, a Current model, and a config/initializers/supabase.rb — and patches config/routes.rb and app/controllers/application_controller.rb so everything is wired up after a single bin/rails server.

Run it once after bundle add supabase-rails. The generator is idempotent: it skips files that already match its templates, runs Thor's standard overwrite prompt for files that have diverged, and no-ops the two file patches when the directives are already present.

bin/rails generate supabase:install

Expected output on a fresh Rails 8 app:

   create  app/controllers/concerns/authentication.rb
   create  app/controllers/sessions_controller.rb
   create  app/controllers/registrations_controller.rb
   create  app/controllers/passwords_controller.rb
   create  app/controllers/otp_controller.rb
   create  app/controllers/oauth_controller.rb
   create  app/models/current.rb
   create  config/initializers/supabase.rb
   insert  config/routes.rb
   insert  app/controllers/application_controller.rb

Files created

Eight files. Each one is small on purpose — the gem ships the real implementation; the host app only owns the override hooks.

PathWhat it is
app/controllers/concerns/authentication.rbA 7-line concern that includes Supabase::Rails::Authentication. ApplicationController includes this concern, which is what gives every host controller authenticated?, current_user, require_authentication, and the full supabase_* helper surface.
app/controllers/sessions_controller.rb3-line subclass of Supabase::Rails::SessionsController. Handles GET /session/new, POST /session, DELETE /session. Empty body — override actions here to customise.
app/controllers/registrations_controller.rb3-line subclass of Supabase::Rails::RegistrationsController. Handles GET /registration/new, POST /registration.
app/controllers/passwords_controller.rb3-line subclass of Supabase::Rails::PasswordsController. Handles the "forgot password" / "reset password" flow at /passwords and /passwords/:token.
app/controllers/otp_controller.rb3-line subclass of Supabase::Rails::OtpController. Handles email/SMS one-time codes at /otp/new, /otp, /otp/verify.
app/controllers/oauth_controller.rb3-line subclass of Supabase::Rails::OauthController. Handles /oauth/:provider/authorize (kicks off PKCE) and /oauth/callback (exchanges the code).
app/models/current.rbclass Current < ActiveSupport::CurrentAttributes with attribute :user, :session. Per-request thread-local store the Authentication concern populates after a successful verify.
config/initializers/supabase.rbSets Rails.application.config.supabase.mode = :web. Ships with commented examples for allowed_redirect_origins, expose_current_user, and the session cookie hash. The framework default is :api, so this file is what flips the gem into cookie-session mode.

Generated file contents

The concern (app/controllers/concerns/authentication.rb):

# frozen_string_literal: true

module Authentication
  extend ActiveSupport::Concern

  included do
    include Supabase::Rails::Authentication
  end
end

A controller subclass (app/controllers/sessions_controller.rb — the other four are identical except for the parent class):

# frozen_string_literal: true

class SessionsController < Supabase::Rails::SessionsController
end

The Current model (app/models/current.rb):

# frozen_string_literal: true

class Current < ActiveSupport::CurrentAttributes
  attribute :user, :session
end

The initializer (config/initializers/supabase.rb):

# frozen_string_literal: true

Rails.application.config.supabase.mode = :web

# Origins the OAuth + password-reset helpers will accept as redirect targets.
# Path-only redirects are always allowed; absolute URLs must match an entry
# below. Defaults to [request.host] at runtime when this list is empty.
# Rails.application.config.supabase.allowed_redirect_origins = ["https://example.com"]

# Expose `current_user` as a view helper. nil = derive from mode
# (true in :web, false in :api).
# Rails.application.config.supabase.expose_current_user = nil

# Encrypted session cookie defaults. `secure: nil` = auto-detect from Rails.env.
# Rails.application.config.supabase.session = {
#   cookie_name: "sb-session",
#   same_site:   :lax,
#   secure:      nil,
#   domain:      nil,
#   path:        "/"
# }

See Configuration for every key the initializer can set, including the ones the template omits (auth, cors, env, supabase_options, oauth_providers, user_model, insert_middleware).

Files modified

Two files in the host app are patched in place. Both patches are guarded by a substring check, so re-running the generator after a successful first run is a no-op on each.

config/routes.rb

A single line is injected on the line directly after Rails.application.routes.draw do:

 # config/routes.rb
 Rails.application.routes.draw do
+  supabase_authentication_routes
   # ... your existing routes
 end

supabase_authentication_routes is a DSL helper installed onto ActionDispatch::Routing::Mapper by Supabase::Rails::Engine. One line expands to the full session / registration / passwords / OTP / OAuth route table — see the routes reference for the per-route breakdown, including the only: / except: filters for mounting a subset.

The patch is skipped if config/routes.rb already contains the string supabase_authentication_routes, or when the file does not exist (e.g. an --api-only Rails app without a generated routes file).

app/controllers/application_controller.rb

A single line is injected into the ApplicationController class body via Thor's inject_into_class:

 # app/controllers/application_controller.rb
 class ApplicationController < ActionController::Base
+  include Authentication
   # ... your existing code
 end

This is the one line that activates everything else — every controller that inherits from ApplicationController now gets the supabase_* helpers, the before_action :require_authentication, and the current_user / authenticated? view helpers.

The patch is skipped if the file already contains the string include Authentication, or when app/controllers/application_controller.rb does not exist.

No database migrations

The install generator writes no migrations — Supabase Auth owns the user table, and Current is ActiveSupport::CurrentAttributes (per-request, in-memory). If you want a shadow users row in your own database so belongs_to :user resolves, run bin/rails generate supabase:user_model afterwards.

Diff summary

A complete "what changed" view of a freshly-generated app, by file:

+ app/controllers/concerns/authentication.rb
+ app/controllers/sessions_controller.rb
+ app/controllers/registrations_controller.rb
+ app/controllers/passwords_controller.rb
+ app/controllers/otp_controller.rb
+ app/controllers/oauth_controller.rb
+ app/models/current.rb
+ config/initializers/supabase.rb

 config/routes.rb
+  supabase_authentication_routes

 app/controllers/application_controller.rb
+  include Authentication

Total: 8 files created, 2 files modified, 0 migrations, 0 lines deleted.

Options

The generator declares no custom flags — it inherits Thor's standard generator option set. The flags worth knowing:

FlagEffect
--force, -fOverwrite every file that already exists, without prompting. Use when re-running the generator after you've intentionally rolled back an earlier version.
--skip, -sKeep host copies for every file that already exists. Useful when you want the routes/ApplicationController patches but not to touch existing controller files.
--pretend, -pDry-run. Prints the create/insert log lines without writing anything.
--quiet, -qSuppress the create/insert log lines.
--skip-namespaceDon't include the generator's namespace in generated paths. No-op for this generator — paths are absolute (app/controllers/..., not app/controllers/<namespace>/...).
--skip-collision-checkSkip Rails' check for filename collisions with existing Ruby constants.
--help, -hPrint the generator's description and option list.

When a file already exists and its content differs from the template, Thor prompts interactively with [Ynaqdh]:

KeyMeaning
Y (yes)Overwrite this file.
n (no)Keep the existing file.
a (all)Overwrite all remaining conflicts (equivalent to --force for the rest of the run).
q (quit)Abort the generator. Files already written stay written.
d (diff)Show a unified diff of host file vs. template, then re-prompt.
h (help)List the keys above.

After the generator

Three things to do before bin/rails server:

  1. Set SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, and SUPABASE_SECRET_KEY — the gem reads these at request time (not at boot). See the env-var resolution table in Configuration. The full Supabase-dashboard → env-var mapping is in step 4 of the Getting started guide.
  2. Open the initializer and uncomment what you need. The defaults are sensible for local dev (path-only redirects allowed, host-only session cookie, expose_current_user derived from mode). Set allowed_redirect_origins before you ship to production, and set oauth_providers if you want the oauth/_buttons partial to render anything.
  3. Verify with a sign-up. /registration/new should render the gem's default form. After submitting, Current.user is populated from the verified JWT claims — drop <%= Current.user&.email %> anywhere in a view to confirm.

Customising the generated controllers

The five generated controllers exist solely as override points. Add an action and call super — the base class handles the Supabase round-trip, your override handles the host-app-specific behaviour:

# app/controllers/sessions_controller.rb
class SessionsController < Supabase::Rails::SessionsController
  def create
    super
    # Custom analytics, audit log, welcome flash, etc.
    AnalyticsJob.perform_later(:signed_in, user_id: Current.user.id) if authenticated?
  end
end

Override the entire action by not calling super; the base class's behaviour is documented per-controller in the controllers reference. For overrides of the supabase_* helpers themselves (e.g. custom error formatting), override the corresponding hook on the Authentication concern instead.

To replace the gem's default views with your own ERB, run bin/rails generate supabase:views — it copies the eight default templates into app/views/supabase/rails/ where Rails' view-resolution order picks the host copies ahead of the gem's. See the supabase:views generator page for details.

Re-running and rolling back

The generator is safe to re-run any number of times:

  • Files with content identical to the template print identical and are not rewritten.
  • Files that have diverged trigger Thor's [Ynaqdh] overwrite prompt (unless --force or --skip is passed).
  • The two file patches (routes.rb, application_controller.rb) substring-check before injecting — never duplicated.

There is no supabase:uninstall generator. To roll back manually:

  1. Remove the eight generated files (the concern, five controllers, Current, the initializer).
  2. Delete the supabase_authentication_routes line from config/routes.rb.
  3. Delete include Authentication from app/controllers/application_controller.rb.
  4. bundle remove supabase-rails.

See also

  • Getting started — the end-to-end quickstart that invokes this generator as step 3.
  • Configuration — every config.supabase.* key the initializer can set.
  • Authentication — the Authentication concern's full helper surface and override hooks, plus the Current.user / Current.session value objects.
  • Controllers — the five base controllers the generated subclasses inherit from, plus the full route table supabase_authentication_routes produces.
  • supabase:user_model — opt-in shadow AR User model + migration.
  • supabase:views — copy the default ERB templates into the host app for customisation.

On this page