moneygun

SHIP YOUR NEXT APP FAST! Rails 8 SaaS Multitenancy boilerplate. Users-Memberships-Organizations. Row-based. Set tenant based on URL params.

145
12
Ruby

Moneygun - Simple Rails 8 SaaS Boilerplate

A production-ready Ruby on Rails boilerplate for building multi-tenant SaaS applications. Built with best practices, modern tooling, and a focus on developer experience.

Ruby on Rails
License

Moneygun features

πŸš€ Features

Core Functionality

  • Multi-tenant Architecture: Route-based organization management
  • Authentication & Authorization: Built with Devise and Pundit
  • Subscription Management: Integrated Stripe payments via Pay gem
  • Team Management: Organization creation, member invitations, and role management
  • Modern UI: Clean, responsive design that you can easily extend
  • Dark mode & Themes

πŸ’‘ Teams as MVP: Teams should be an MVP feature! - Learn why implementing teams early is crucial for SaaS applications.

Deployment

Deploy to Render

Deploy to Heroku

Developer Experience

  • Complete Test Coverage
  • Nested Resource Generation: Fast development with nested scaffold generators

🎯 Why Moneygun?

Route-Based Multi-tenancy

Unlike traditional approaches (subdomains, user.organization_id), Moneygun uses route-based multi-tenancy which offers several advantages:

  • Support for multiple organizations in different browser tabs
  • No complex subdomain configuration required

πŸ“š Video Tutorials

  1. Row-level Route-based Multitenancy
    Learn how to implement row-level route-based multitenancy in Ruby on Rails

  2. Multitenancy & Teams Boilerplate
    Learn how to implement teams and multitenancy in your Rails application

  3. Add ActsAsTenant to Existing Application
    Step-by-step guide to adding ActsAsTenant to your existing Rails application

  4. Build Your Next B2B SaaS
    Enable Subscriptions with Stripe and launch your B2B SaaS application with Moneygun

Resource Organization

Resources are organized in a logical hierarchy:

/organizations/:id/projects/:id/tasks/:id

This structure provides:

  • Clear resource ownership
  • Intuitive navigation
  • Easy access control
  • Simplified querying

πŸ› οΈ Getting Started

  1. Clone the repository:
git clone [email protected]:yshmarov/moneygun.git your_project_name
cd your_project_name
  1. Set up the application:
bundle install
rails db:create db:migrate
  1. Start the development server:
bin/dev

πŸ’³ Stripe Integration

Moneygun uses the Pay gem for handling Stripe subscriptions. Here’s how to set it up:

1. Configure Stripe Credentials

Add your Stripe credentials to your Rails credentials:

rails credentials:edit

Add the following structure:

stripe:
  private_key: sk_
  public_key: pk_
  webhook_receive_test_events: true
  signing_secret:
    - whsec_

2. Create Stripe Products and Prices

You can create the required Stripe products and prices in two ways:

  1. Automatically via seeds:

    rails db:seed
    

    This will create a β€œPro plan” product with monthly ($99) and yearly ($999) prices.

  2. Manually in Stripe Dashboard:

    • Create a product named β€œPro plan”
    • Add two prices:
      • Monthly: $99/month
      • Yearly: $999/year

3. Configure Plans

Add your Stripe price IDs to config/settings.yml:

shared:
  plans:
    - id: price_xxx # Monthly price ID
      unit_amount: 9900
      currency: USD
      interval: month
    - id: price_yyy # Yearly price ID
      unit_amount: 99900
      currency: USD
      interval: year

4. Stripe webhooks

For development, Stripe webhook listener is already configured in Procfile.dev

stripe listen --forward-to localhost:3000/pay/webhooks/stripe

To enable webhooks:

  • Development: Click here to create a new Stripe webhook with all the events pre-filled.
  • Production: Click here to create a new Stripe webhook with all the events pre-filled.

Example production webhook url: https://moneygun.com/pay/webhooks/stripe

🎨 Theme Configuration

Moneygun comes with built-in support for multiple themes. The application supports:

  • Default Theme: Light mode with gray background
  • Midnight Theme: Dark mode with a sleek, modern look
  • GitHub Theme: GitHub-inspired color scheme

Switching Themes

Themes can be applied by adding the appropriate class to the HTML element:

<html lang="en" class="h-full bg-gray-50 text-gray-900"></html>
<!-- Dark midnight theme -->
<html lang="en" class="h-full bg-gray-50 text-gray-900 midnight"></html>
<!-- Dark GitHub theme -->
<html lang="en" class="h-full bg-gray-50 text-gray-900 github"></html>

Require active subscription to access a resource

You can use the require_subscription before_action to protect routes:

before_action :require_subscription

private

def require_subscription
  unless current_organization.payment_processor.subscribed?
    flash[:alert] = "You need to subscribe to access this page."
    redirect_to organization_subscriptions_url(current_organization)
  end
end

Subscription Status Indicators

Use the subscription status helper to show subscription state:

subscription_status_label(organization)
# Returns:
# πŸ”΄ - No subscription
# 🟠 - Subscription cancelled (on grace period)
# 🟒 - Active subscription

πŸ‘·β€β™‚οΈ Development Guide

Resource Generation

Generate nested resources quickly using the nested_scaffold gem:

rails generate nested_scaffold organization/project name

Authorization

Generate Pundit policies for your resources:

rails g pundit:policy project

Best Practices

Resource Associations

Always associate resources with membership instead of user:

# βœ… Correct
class Project < ApplicationRecord
  belongs_to :organization
  belongs_to :membership
end

# ❌ Avoid
class Project < ApplicationRecord
  belongs_to :user
end

Organization Scoping

Scope downstream models to organization for easier querying:

class Task < ApplicationRecord
  belongs_to :organization
  belongs_to :project
end

πŸ§ͺ Testing

Run the test suite:

rails test:all

Code Quality

# ERB linting
bundle exec erb_lint --lint-all -a

# Ruby linting
bundle exec rubocop -A

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Design inspiration from Basecamp, Linear, Trello, Discord, and Slack
  • Bullet Train for SaaS patterns and inspiration (obfuscates_id, super scaffolding, teams architecture)
  • Jumpstart Pro & co for maintaining the magnificent gems pay, acts_as_tenant