Modeling a multi-tenant rails app so that it's easy to maintain

472 views Asked by At

I'm building a multi-tenant rails app that is using a shared database where data is siloed by scoping everything to each account (similar to Basecamp 3)—rather than with separate tables and subdomains. The approach I'm taking is described here.

Each account will have its own data (e.g. products, inventory), and many users with different roles (e.g. account owner, employee, customer, etc.). I'm using Clearance for User signup and login.

It seems like there are two approaches that I could take with modeling an app like this:

  1. An account owner signs up and creates their account sorta like creating a profile. I'd create the account via nested fields on the sign up form. Everything inherits from the Account owner like this... enter image description here

  1. Or, when a new user signs up a new Account is created and associated with that User (should this happen with a callback?). Everything (such as products and other users like employees or customers) inherit from the account, not the account owner. The account owner is just another User that belongs to the Account.

It seems like option 2 is the simpler solution, but I'm blocked on how to create the Account when a new user signs up via Clearance. I've gone into more detail on this problem here, but I'm worried that the way I'm modeling my app with Option 2 is not ideal.

Which one of these approaches is going to be simplest to setup and maintain? Or, is there another way to model this that I'm missing?

Because I'd eventually like the site to have some users that are customers, should I take the approach of using Subdomains (like Shopify?).

1

There are 1 answers

0
Lee McAlilly On

So, I'm not sure how well this solution will work as the app evolves over time, but I ended up going with this flow for now if it helps anyone else with a similar problem:

  1. User signs up via clearance sign up form at /signup
  2. After signing up they are redirected to accounts/new if they have not created an account
  3. Accounts belong_to User and every User has_one Account
  4. Everything else, like Products, belong_to the Account
  5. User roles are set based on how you sign up. So if you sign up from the homepage you are the Account Owner by default.
  6. Access control is determined by User roles and Pundit.
  7. Data is siloed because everything else, like products, belong_to the Account

Here's a sketch of the relationships: enter image description here

Here's the code:

accounts_controller.rb

# POST /accounts
  def create
    @user    = current_user
    @account = @user.build_account(account_params)

    respond_to do |format|
      if @account.save
        format.html { redirect_to @account, notice: 'Account was successfully created.' }
      else
        format.html { render :new }
      end
    end
  end


  def account_params
    params.require(:account).permit(:company_name, :user_id)
  end

models/account.rb

class Account < ApplicationRecord
  belongs_to :user
end

models/user.rb

class User < ApplicationRecord
  include Clearance::User
  has_one :account
end