Multi Model Sign-up Wizard
Related to my previous thread (https://gorails.com/forum/structure-guidance-multi-tenancy-authentication-authorization) I plan to have authorization with Devise and some sort of role based system (perhaps Pundit) tied to a Company model.
When the user signs up they are creating the new Company record and a user / role at the same time. I can see a few issues and I am not sure how to handle them:
1.) Email adress vs username
Some quick Googling indicates that email addresses as username might be a bit more prone to security issues but personally it's nice to use them as it's easy to remember and saves one less field from the scheme. Any thoughts?
2.) Duplicate Companies
With my target market I don't this being a big issue. I am going to require the company name - ABC Widgets Inc. for example. It is possible for two people to sign up "ABC Widgets Inc." and "ABC Widgets" etc. I could do a validation search to look for similar companies but that opens up privacy issues. I was also thinking that I could add a search on existing user email domains too. If [email protected] tries to register "ABC Widgets Inc." and then [email protected] tried to register "ABC Widgets" that would be a chance to stop them and email Sally about Tom's interest.
My first thought is to just leave it along an monitor new signups etc and contact the users when issues arise. I may me making this a bigger issue.
3.) Updating two models at the same time
The user fills out the sign-up form and then my controller chugs away planning to add a Company, User and Role record. I need all three to execute successfully otherwise roll back - can you do that in Rails? The Role is easy - it's a new company and in my system the user could actually already exist.
- It is usually wise to always require an email and optionally do the username. One reason is: how does a user recover their password if you don't have their email?
On a side note, you can easily add usernames to Devise and they definitely can be easier to remember. Check this out if you're interested in sign-in with both. https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address
You know how some sites (like Slack.com) use a subdomain for the company? That's basically for exactly that problem and each company gets to choose their subdomain or "username" if you will. You could have two "ABC Widgets" companies but they would have different subdomains.
You can use nested model validation to take care of that. If any of the records isn't valid, it will roll them back. You'll want to do nested form for those things. Like a
fields_for :roleso that it's all contained properly. More info on that here: http://homeonrails.com/2012/10/validating-nested-associations-in-rails/
I am going to go with the email only. It's just easy - I personally hate having to pick a username. My email is the easiest thing to remember.
Here is a great link I came across on the very subject:
It even gets into login vs signing and signup vs register.
Thanks for the tip on the nested model validation :)
I was tying to implement this and had a revelation - I need to register the Company and then using nested forms to create the user and role. Once the user registers the company the user is automatically created (unless they exist) and then the role is created to glue the two together.
Now - I have already created my default Devise install on the User model. I still want to use Devise for authentication but can I still use it for registration or I am overriding manually? Once a company is created all new users created under that company will be by another existing user. You will not be able to signup unless you are creating a new company.
I think in this case I can handle the validations in my controllers. It's a bit ugly with all the :through associations.
Are you trying to create a company before they create a user on sign up?
What I do in this case is use the user registration form and do
fields_for :company inside of it. That way you can't create a company without attaching it to a User. I can ask for teh company information first, but in the same form I also submit the user details which save the company and associate the user as the "Owner" of the company.
Am I following you correctly?
Yes - that's essentially what I am doing.
My system has some differences. First off the user could exist already. As long as the company is unique they can continue.
Second I have a Role model that associates the User to the company. I need to create / identify the user, create the company and a role all at the same time and like I mentioned roll it all back if any validation fails.
This is where I struggled with even letting people sign up directly. At first I thought I would set up a company manually and add the first owner user. This way I can watch for duplicate companies etc outside of a normal validation etc.
However with a direct sign up people can get into a trial account an start test driving the site right away.
I forgot to mention - I tried your method and the user gets created but the company is not getting created and there is no errors or even any active record activity in the logs when it happens. I suspect I have my associations messed up because there is no direct link between User and Comapny with Role in the middle.
Ok.. here is a StackExchange post on this:
It has my Models etc.