We've moved discussions to Discord

Can you have a non-personal team without the personal team?

Richard Wiltshire
Can you have a non-personal team without the personal team? For instance, I would like to create an app for a dentist's office. I would like to have the first non-personal team created when the doctor registers, and then they can invite the staff members to the team. Maybe the doctor can create new teams for additional practice locations. In this scenario, a personal team does not make sense and perhaps even confuse the staff. Is this scenario possible and stay within the design of the template? Thanks in advance for any thoughts.
Chris Oliver
What I would probably do is a couple of things:

1. Comment out the personal team in user_teams.rb
2. Prompt the user to create a team after sign up

I would probably add a Location model and a LocationUser model to keep track of which users have access to which locations. It would work similar to Teams, but would allow you to have more control over how that worked.

Billing is attached to Teams, so if you were to repurpose to represent locations, I think you would end up making things messy.
Patrick Misch
I've been dealing with this problem too as my app has no need for a personal team. What I've done is just set 'personal' to false in the create_personal_team method in user_teams.rb

Still need to 1) Allow for setting a Team/Company name on sign up and 2)  making sure invited users don't get a new team created automatically for them.

Haven't put too much thought into any of this yet, so definitely open to better solutions.

Chris Oliver
Patrick Misch sounds like it would work to me. 👍

This gave me an idea to make the personal team configurable from the Jumpstart Admin area. That way we could allow you to turn it on/off easily which would disable the callback and might add/remove the team name during registration or something.
Ryan Chin
I have the same problem (no need for a personal team).  I think making personal team functionality configurable would be worthwhile.
In my app, I do not need the personal team.  Any time frame of the the configurable personal team switch ?

Chris Oliver
No time frame on it. I'm working on multitenancy right now, so maybe I can roll it into that since it's dealing with teams.
Chris Oliver
For now, I would simply just ignore the personal team and not associate your records with it.
Richard Wiltshire
Thanks for the suggestions  Chris Oliver and  Patrick Misch ! Sorry for the delay. I just circled back to this part of the code. I going to use the "false" personal team as a starting point!
Borja Soler
I did that Richard Wiltshire and it's working fine for me, now when a user sign ups it gets only team accounts. 
Matthew Lindfield Seager
I'm a bit late to the party and the "Enable Personal Accounts" toggle has already been added to the config (thanks Chris Oliver ). That being said I was a bit surprised that it still created an account named after the user on sign up... I expected user sign up and account creation to be completely separate at that point.

I've just gone back to the admin page and it clearly says "Disabling personal accounts will automatically create a regular account for each user instead." but I mustn't have read (or absorbed) that.

I get that it's tricky to know exactly what people are after when they uncheck that box but maybe it would be helpful to include some links to documentation on some common scenarios? Or split it into 3 options...? Something like:
  • Enable Personal Accounts (default)
  • Create a regular account at user sign up
  • Don't create any account at user sign up
Chris Oliver
I don't know if we'll officially support turning off the Account completely.

If you don't want users to know about Accounts, you just remove links from the navbar and you're done. 
Ryan Chin
Hi Chris Oliver - can you please help me figure out how to set things up.

Here's my use case: I'm trying to create an enterprise SaaS tool - like a  Slack or Office 365. In enterprise situations, one person signs up for the main account that's billable, and other users sign-up and are related to that account.  

From your last comment, I understand that the users that sign-up to become related to the main account can have their own account info hidden. However, I don't want free enterprise billing plans [for accounts], and I don't want to charge the users that becoming a member of the paying account.  

In essence, I need the enterprise accounts to be paid, and the accounts automatically created for other users to be free.

What's the best way to handle this? 

Thanks Chris!
Chris Oliver
Ryan Chin Think of them as AccountUsers. The main Account is paying, and the AccountUsers who are attached all have access.

You can add a step to the registration process to associate them with an account if they used their work email like Stripe does, or just have the existing account users send email invitations.

You will basically just ignore the default accounts for users. 
Ryan Chin
Thanks Chris Oliver .  

Do you think that you'll be doing a Go Rails episode on multitenancy (with Jumpstart) soon?
Chris Oliver
I've got an episode on acts_as_tenant in my todo list for this week. :)
Ryan Chin
Nice, it would really help me to see how you would do it!  If possible, could you incorporate having a user joining a main account (or team) that's paying?
Matthew Lindfield Seager
If I'm reading it correctly I'm after a similar thing to Ryan... one signup flow to register an Account and another (more common) signup flow to register as an Account User for an existing account.

By disabling personal accounts I thought I was doing the latter (and that I would then have to build my own mechanism to create Accounts... or maybe just create them manually).

Hence my suggestion for the three options... re-wording the third one:
  • Enable Personal Accounts (default)
  • Create a regular account at user sign up
  • Don't create any account at user sign up Associate user with an existing account at sign up

I'm envisaging a workflow where people (who haven't received an invitation) can request access to an existing account and then the account owner can approve or deny their request.
Chris Oliver
If it ends up being a common thing, sure I'd consider adding that option. 

There's a lot of unique considerations (how do they choose the existing account? how do approvals work? What extra information do you need to collect? etc) that I think make this a pretty complicated to build into the template itself though.

The simplest option would be to have users visit an account's page (like subdomain) and have a controller where they can create a AccountRequest (or whatever you want to call it), fill out any details there to apply, and then Account admins can review those, if approved, then they just create and send an AccountInvitation to the user using the existing stuff for that in Hatchbox. 
Ryan Chin
My use case is indeed similar to Matthew's.  I'm creating an app where the vast majority of users will not be paying, and they will just be members of a paid account - similar to other SaaS Enterprise apps like: Office 365, Slack, Adobe Analytics, etc.  I imagine people joining by being invited by the admin via email (either specifying one, or many, email addresses).

For billing, I want to have different plans based on the number of users (1 = 1-99 users, 2 = 100 - 499 users, etc.).

I'm curious how other people plan on using multi-tenancy.  

Will most of your users be "standalone" (no other users associated with the account), or will the majority of users be attaching to another [billable] acccount?
Matthew Lindfield Seager
EDIT: I just re-read your reply Chris Oliver and my long answer basically just repeated what you suggested. Sorry!
TLDR:
  1. Is there a simple way to have the new_user_registration_path create a User and an AccountRequest (based on current_account being set) rather than a User and an Account?
  2. Bonus points, is there a simple way to also ask for an Account Name on sign up if current_account is not set?

How do they choose the existing account?
They don't... it's chosen for them based on  current_account (i.e. path, subdomain, or domain).
If you want to create an account you go to the main app page; myapp.com
If you want to join an account you go to an account page; myapp.com/2, acme.myapp.com or app.acme.com.

How do approvals work?
Ideally, almost the same as AccountInvitations... Create an AccountRequest (or maybe make AccountInvitation slightly more generic to be able to handle both cases). Instead of the user accepting or ignoring the AccountInvitation, the admin accepts, ignores or rejects the AccountRequest.

What extra information do you need to collect?
None in the base case... the only change is what Patrick Misch mentioned: "Allow for setting a Team/Company name on sign up"... but only if you're creating an account from the main app page.

Reading through the thread I think this would help Richard (the OP), Patrick, David, Ryan and myself (and presumably others who haven't asked).

If this doesn't make sense in the app template, I'd love some help figuring it out (perhaps a guide?).

I'm still trying to figure out:
  • if I need an alternate new_user_registration_path for when a new Account is being created
  • or maybe something needs to happen in Devise... do I override, or add behaviour to #create in app/controllers/users/registrations_controller.rb?
  • or maybe I need to change what happens in #create_default_account in app/models/concerns/user_accounts.rb based on whether current_account is set?
  • or maybe I'm barking up the wrong tree

Matthew Lindfield Seager
  1. Is there a simple way to have the new_user_registration_path create a User and an AccountRequest (based on current_account being set) rather than a User and an Account?
  2. Bonus points, is there a simple way to also ask for an Account Name on sign up if current_account is not set?

I got 1 working. It feels like an ugly pile of hacks but...

I set linked_account_id to current_account&.id in the form (and added :linked_account_id to permitted params in ApplicationController).

I then added a virtual attribute to UserAccounts (with attribute :link_account_id) and changed the after_create hook to create_or_link_account... If linked_account_id is nil it calls the old create_default_account method, otherwise it finds the account with that ID and creates an AccountUser (N.B. not an AccountRequest at this stage).

Now that I think about it, the same approach could be used to collect an account name on the form (if current_account is nil) and pass that through to User.

If anyone has a better approach I am all ears but for now I just want to try and get this up and running.
Chris Oliver
Made a video on how to create an account on registration and added it to the screencasts docs page.
Ryan Chin
Thanks Chris! 

And thanks  Matthew Lindfield Seager  for surfacing this - this is exactly what I need, too.
Matthew Lindfield Seager
Thanks Chris!!! I started trying to go down the accepts_nested_attributes_for path but I got lost figuring out how to get it working with Devise. This is a fantastic help!!!
Borja Soler
Thanks Chris!

Matthew Lindfield Seager  or anyone developed a solution for invited users? I would like not to ask for create an account name to users that have been invited to an existing account
Matthew Lindfield Seager
Have a look at using current_account Borja Soler .

I found that when you visit the registration page using a subdomain, domain or with /:account_id/ in the path then current_account will be set which lets you distinguish between someone registering as a user in an an existing account or someone registering for a brand new account.

In my app/views/devise/registrations/new.html.erb file I then controlled the display of the account name field using the following:

...

    <% if !!current_account %>
      <%= f.hidden_field :link_account_id, readonly: true, value: current_account.id %>
    <% else %>
      <div class="form-group">
        <%= f.label :account_name, "Account name" %>
        <%= f.text_field :account_name, autofocus: !current_account, placeholder: "Acme Inc.", class: "form-control" %>
      </div>
    <% end %>

    <div class="form-group">
      <%= f.label :name, "Full name" %>
      <%= f.text_field :name, autofocus: !!current_account, autocomplete: "name", placeholder: "Steve Jobs", class: "form-control" %>
    </div>

...

I haven't yet updated that to use accepts_nested_attributes_for like Chris demonstrated- and I haven't yet looked at invitations- but hopefully that gets you headed in the right direction.

P.S. For bonus points I updated the autofocus using the same logic so the first field always gets the focus
Ryan Chin
Matthew Lindfield Seager , I will definitely need this feature going forward.  I want to build out the core features on my app first.

One question I have though, I see the account_invitation functionality in the code, but I don't see a place for the admin to trigger them in the UI.  Am I missing a view?  Or maybe I should ask, how are you allowing admins to invite and/or add account_users?

Thank you!
Matthew Lindfield Seager
Can't tell you much but rails routes shows there's a new_user_invitation route at localhost:3000/users/invitation/new (view is in app/views/devise/invitations/new.html.erb).
Ryan Chin
That works, thank Matthew Lindfield Seager

Now I just have to figure out to let the account admin mass upload a CSV of email addresses to invite a bunch of users at once.
Chris Oliver
The link to invite is on the team's show page in settings. Only for impersonal teams, of course. 👍

As for uploading a CSV, I would probably add like an account_users/import controller + routes and that way it can be nicely organized.
Notifications
You’re not receiving notifications from this thread.