rails: how to validate uniqueness of a field in two tables? - ruby-on-rails

I have two tables in my app's database for two kinds of users, therapists and patients, both sign in/out with a username and password, I want to make sure that there can't be a therapist and patient with the same username, how can I do that?
also, is it possible to use the same sessions controller for both therapists and patients?

Refactor Your Design
You shouldn't have two different tables for users. You should probably have a single User table, with a field that designates the role of the User. This makes it particularly easy to select the user's role using radio buttons or a drop-down in the web application, and also allows you to enforce uniqueness on aspects of a User record.
However, why is it impossible for a patient named "John Smith" to have a therapist named "John Smith?" I'd think about that before enforcing that particular uniqueness constraint.
Finally, a session is generally shared across controllers, and a controller can certainly read from more than one model at a time. In your case, refactoring to a common User model will reduce the need to do something complex in this regard.

Related

Multiple Devise Users: Multiple Models or Inheritance?

In my Rails application with Devise, I plan to make multiple types of Users (Student, Teacher, and Admin). They have a number of shared attributes such as username, email, password, etc, but with some differences. Students will be able to interact with the content posted by teachers (and probably each other), Teachers can make classes and post content and interact with their students, and Admin will likely have control over most everything (including taking down users, content, etc.)
I am trying to figure out the best way to do this, and preferably with the least headaches as I am still new to Rails. Should I make multiple Devise Models, one for each type of User, or should I make multiple models inherit from User (which I believe is called Single table inheritance?) I am fairly open to trying either one, but I am unsure of which is the best way to go
If you want different authorizations (for example Admin & User) level you can use Pundit.
If you have different roles with the same authorizations (like Student and Teacher in the same context) you should use Inheritance and Concerns, maybe defining a base controller from which all other controllers can derive.

Should I use Multiple user models or one big user model in Devise

I'm doing a Rails project with three user types: students, teachers, and administrators. Each user type has a dozen+ columns unique to that role. Initially I thought I'd create separate models for each type, but having a single shared login seems to pose a problem (I've found a workaround on Stack Overflow, but its complex and a few years old).
What is SOP for situations like this? Is it kosher to have a single user model with 24+ columns that will always be empty depending on the role type? Or am I better off sticking with three separate models and trying to hack a workaround to make a shared login?
Thanks!
EDIT: Oops, forgot to add the third workaround which I'm favoring: having a single user model with only columns relevant to login, and then models for each role that hold columns specific to each user type. Is that a good call?
You could make two separate models, Student and Teacher. Then add an admin:boolean field for teacher. I am assuming most admins will probably be teachers? Even if that is not the case you could just default that all admins are teachers. Three separate models is terribly bulky.

Add user information in additional or current model?

I currently have a "user model", which is managed by the gem devise. Right now, that model has only the most basic information (first name, last name, email, password).
Now I am wondering wether I should add additional user fields as an additional, associated model (e.g. named "userprofile") or just add the additional fields to the existing "user" model (profile picture, years of experience, description about the teacher etc.). What is the common practice?
I am looking forward your help.
Best regards,
Alex
When you call current_user (or any devise helper method per se), it retrieves all the fields from the database for that user record, whether or not you need 'em. So, it's better to have as lesser fields in the devise's user model as you can. If you want to create a user profile with additional fields, better create a new associated model.
In general, add those kinds of "simple" attributes directly to the User model (i.e. years of experience, description, etc). As you add more complicated information about a user (e.g. job history), or if you have a significant amount of these attributes such that it might start impacting performance, you may want to start adding associated models. But otherwise it's probably not worth the added complexity.

How to model different users in Rails

Question
I have a User model with authorisation and authentication logic built.
Now I realise I have three different types of users. I want to store different information about each of them.
What is the best way to handle this in Rails?
Thoughts based on current reading
I've looked at STI but from what I've read feel it is inappropriate because I'll end up with a lot of NULL fields in my database.
Ideally I'd like to not duplicate the authentication / authorisation logic for each of the three user types.
Each user will also have different functionality within the application.
You can try using polymorphic associations and creating table users with data that all types of users have and putting other data in seperate tables. Railscast epizode covering this topic.
There are lots of ways to do this. Here's one approach:
Instead of thinking of different types of users, you could think of roles that a user has.
For example, if a user could be a butcher, baker, or candlestick maker, you could have four tables: users, butchers, bakers, candlestick_makers. The latter three role tables each have a user_id column; they "belong to" the user.
If you need to enforce that a particular user has only one role, you will have to do that in the application (since this database schema would allow multiple roles for a single user).
This method is good if there is a lot of stuff that would belong in those role tables. If not, leaving some NULL columns on the users table probably won't kill you.

RoR table inheritance?

Scenario: I have a users table in my application. I also have two subclasses of users, lets say contributors and viewers. Each user group must have an entirely different set of attributes but they both share certain user properties (login, password, name).
What is the best way to implement this using Ruby on Rails?
I think single table inheritance would leave me with too many null fields.
I think linking three tables (users, viewers, contributors) would work fine, but then when wanting to edit any information i have to do: #user.viewer, while i would love to be able to just do #viewer.
Any ideas of the best solution?
I would probably go with the three tables approach. Data integrity is king over code cleanliness.
If you want to make it look neater, put virtual attributes on the Viewer and Contributor models that make it look like the User attributes are local. You can make it a module and include it in both Viewer and Contributor models.
You can also set up an :include => :user on the default finders so that you don't get an extra query when using those fields.
I'm extremely caffeinated right now, so comment back if that doesn't make sense :)
don't compromise the database schema, make it fit best. I like the three table method. If you do the database bad, the application will have very hard to fix issues later, run slow, etc.

Resources