Account and user management

At the core of the Teams component are 3 models:

  • Account
  • User
  • AccountUser

Here's your mental model for how you should think about these models:

  • An Account is a team. You might think of an account as a "company" or "organization". But even in single-user apps, one person owns an account.
  • A User is a person. A user can own or be a member of multiple accounts.
  • An AccountUser is a person's membership in an account.

Think of it like this: If an "Account" is a company, and a "User" is a person, then an "AccountUser" is that person's ID badge that they wear to walk into the company's office building and access the company's... stuff.

The Account Owner

When a new user signs up for the application, the following happens via an after_create callback in the User model:

  1. A new User record is created.
  2. A new Account record is created.
  3. A new AccountUser record is created, with the user_id and account_id set to the newly created User and Account records.

The accounts table also has an owner_id column, which references the ID of the User that owns the account. There can only be one owner of an account.

Roles & Permissions

The AccountUser model has a role enum column. When installed, it comes with two possible roles (you can add more, as needed):

  • admin
  • member

Newly created AccountUser records are given the admin role by default.

The User model comes with several methods you can use to check a user's role in an account:

Copy
def account_user(account)
  account.account_users.find_by(user: self)
end

def account_user?(account)
  account_user(account).present?
end

def account_role(account)
  account_user(account).role
end

def account_owner?(account)
  account.owner_id == self.id
end

def account_admin?(account)
  account_role(account) == 'admin'
end

def account_member?(account)
  account_role(account) == 'member'
end

Authorization

The Teams component inserts a few methods into your application_controller.rb file, which can be used to authorize only account users or account admins to specific controller actions.

Copy
def authorize_account_admin_user
  unless current_user.account_admin?(current_account)
    redirect_to root_path, alert: "You are not authorized to access this page."
  end
end

def authorize_account_user
  unless current_user.account_user?(current_account)
    redirect_to root_path, alert: "You are not authorized to access this page."
  end
end

To ensure that a specific controller action can only be accessed by members of an account (any member, any role), add this as a before_action:

Copy
before_action :authorize_account_user, only: [:specific_action]

To ensure that a specific controller action can only be accessed by account users with the admin role, add this as a before_action:

Copy
before_action :authorize_account_admin_user, only: [:specific_action]

Users in multiple accounts

The relationship between a User and Account through AccountUser enables users to be members of (or owners of) multiple accounts. They can easily switch between accounts using the built-in account switcher.

Instrumental Components

I created Instrumental Components to make designing and building professional apps with Ruby on Rails easy, fast, and fun. I use it on all of my projects and I hope it helps you build something great.

Brian Casel
Brian Casel
Creator of Instrumental Components
Learn more Send me a question or request