# Multi Tenant Setup

Implements URL-based multi-tenancy with account scoping, membership patterns, and data...

- Repository: https://github.com/ThibautBaissac/rails_ai_agents (671 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-06-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add ThibautBaissac/rails_ai_agents --skill multi-tenant-setup -g -a claude-code -y`
Codex: `npx skills add ThibautBaissac/rails_ai_agents --skill multi-tenant-setup -g -a codex -y`
Cursor: `npx skills add ThibautBaissac/rails_ai_agents --skill multi-tenant-setup -g -a cursor -y`
Gemini CLI: `npx skills add ThibautBaissac/rails_ai_agents --skill multi-tenant-setup -g -a gemini-cli -y`

## Description

Implements URL-based multi-tenancy with account scoping, membership patterns, and data isolation following 37signals patterns. Use when setting up multi-tenant architecture, account isolation, membership management, or when user mentions multi-tenancy, accounts, or tenant separation. WHEN NOT: For basic model setup without tenancy (use model-patterns), for auth/session setup (use auth-setup).

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Multi-Tenant Setup

## Philosophy: URL-Based Multi-Tenancy, Not Subdomain or Schema

- URL-based: `app.myapp.com/123/boards/456` (account_id in path)
- `account_id` on every table (no foreign key constraints)
- `Current.account` set from URL params for all requests
- All queries scoped through `Current.account`
- UUIDs everywhere (prevents enumeration attacks)
- No default scopes (explicit scoping preferred)
- No Apartment gem, no subdomain routing, no schema separation

## Project Knowledge

**Stack:** URL-based multi-tenancy (`/accounts/:account_id/...`), Current
attributes for account/user context, UUIDs for all primary keys, single
database with single schema.

**Auth:** Custom passwordless with `Current.user`, users can belong to multiple
accounts, account membership controls access.

**Commands:**
```bash
rails generate model Account name:string
rails generate model Membership user:references account:references role:integer
rails generate migration AddAccountToCards account:references
```

## Pattern 1: Account Model and Memberships

See @references/membership-patterns.md for full details.

```ruby
# app/models/account.rb
class Account < ApplicationRecord
  has_many :memberships, dependent: :destroy
  has_many :users, through: :memberships

  has_many :boards, dependent: :destroy
  has_many :cards, dependent: :destroy

  validates :name, presence: true, length: { maximum: 100 }

  def member?(user)
    users.exists?(user.id)
  end

  def add_member(user, role: :member)
    memberships.find_or_create_by!(user: user) do |membership|
      membership.role = role
    end
  end

  def owner
    memberships.owner.first&.user
  end
end

# app/models/membership.rb
class Membership < ApplicationRecord
  belongs_to :user
  belongs_to :account

  enum :role, { member: 0, admin: 1, owner: 2 }

  validates :user_id, uniqueness: { scope: :account_id }
  validates :role, presence: true

  scope :active, -> { where(active: true) }
end

The rest: https://github.com/ThibautBaissac/rails_ai_agents/blob/HEAD/.claude_37signals/skills/multi-tenant-setup/SKILL.md
