I have 4 tables
Account
Admin
User
Role
The account table contains the email and password to login.
An account can either be an admin or an user.
An user has a registerdate
An admin has an adminnumber, but no registerdate (different attributes)
The role table contains the role name, either admin or user.
An account currently contains foreign-key relationships with all other tables. This isn't ideal, since depending on the role, one of the tables will be left empty.
I need all account to be in the same table, yet depending on the role it should have different links and attributes.
What is the best way to tackle this?
I use MSSQL
Related
I have a web application that reads data from a DB.
I have different users in my web-app and I'm thinking of delegating the functionality to determine "who can see what" to the DB instead than to the web-app.
Example:
On my DB I'm storing data for different customers. On the same table, I'm storing data for different customers, each row has a "customer" field that identifies the customer to which the row belongs. When the web-app queries the previous table, as the users in the DB are equal to the users in the web-app, the DB will return to the web-app only the rows to which the user has permissions to SELECT.
To implement this I have thought on the following process:
Use ROW-LEVEL SECURITY ACCESS to create a role per each customer. That role will only allow querying rows with Customer='CUSTOMER_NAME'
As the same CUSTOMER could have different types of users (EX: Marketing/Sales users). I want to create a common role for all customers that will filter the data that each type of user could SELECT.
I don't know if I could create a ROLE that will limit the rows that a certain user can select (EX: All the rows with CUSTOMER='CUSTOMER_NAME') and then grant another ROLE to the same user that will limit more the rows that the user can select (EX: All the rows related to a certain department: Marketing/Sales).
Are the roles applied from more restrictive to less? If so, my desired outcome is to have a single "Marketing" role with access to all Marketing-related rows and then to have a single "Customer" role with access to all Customer-related rows. Then the user with those roles will only be able to see Marketing related rows but only for a certain customer.
Is there any other way to do this?
I need to create a system that allows both individual users and groups (e.g., a company) to sign up for a subscription service.
The procedure for signing up for a group membership will involve a user paying for as many users as they require (e.g., 5) at sign up. Once they have paid they will be able to create these other users (i.e., have admin functions) that will be associated with this group (e.g., other members of their company). (They will be able to pay for more users for their group at a later date if they wish.) A user cannot be in more than one group. The original person that signed up on behalf of a group can assign admin roles to these newly created members.
For login purposes, I would like to have both individual users and group users in the same table of the database. For example, it could be called and have columns (to keep things simple):
user table:
user_id
username
I then thought that there must be a second table that shows the links between users (i.e., which belong to which group). Let's say that this is:
groups table:
group_id
user_id
I am guessing that this is a one-to-many relationship as many users can be in one group, but each user can be in only one group.
In order to assign the proper roles to the user that signed up on behalf of a group there would be another table called:
roles table:
role_id
user_id
This would allow some users to have permissions of admin rather than just user. I would then just have to lookup the user_id's of the admin role (a specific admin user_id) when they logged in and this would give them access to the correct people in their group.
Before I go ahead designing this database I was wondering if this is an appropriate database design to go about creating these individual and group users or if there is a better setup?
FURTHER INFO: There are two sign up forms: an individual sign up form and a groups sign up form.
For an individual, we will record their "username", their user_type (individual) and assign them a role of "user". They do not need to be assigned a group id and we will not need to convert their membership to a group membership later on.
For the user who signed up as a group using the group sign up form, we will record their "username", their user_type (group), no. of memberships purchased (e.g., 5), a group id (e.g., a unique integer) and assign them a role of "admin". Because they have purchased multiple memberships, they will be able to create/add new users to their group upto the number purchased. They can assign each new user a role of either "user" or "admin". A role of "user" in both individal and group membership has the same permissions, so there are only two types of role.
As such, I had planned a createUser() function that creates:
For an individual: username, user_type(individual), role(user)
For a group: username, user_type(group), group_id, no_purchased, role(admin)
For a new member of a group (created by admin): username, user_type(group), group_id(the same as the admin), role(admin or user)
I had then planned to create a checkUser() function that:
Gets their id, username, etc...
Checks if they are an admin or user.
If admin, then gets the users/admins that are in the same group as them.
Most calls to the database will be to login (i.e., username/password). I was looking to see what the simplest database structure would be for this situation.
I feel like you might make your life simpler if you consider individual users as groups users with only one member. This will also give you flexibility in the future if an individual user would like to expand into a group?
On the other hand you can keep it as you have it but I wouldn't bother specifying the user type. That can be derived based on if they belong to a group or not.
Many ways to tackle this problem...
Many of us have probably encountered this situation. I want to build an app which supports multiple user roles and don't want to use gems for that process.
I have 4 types of users:
Admin
Teacher
Student
Librarian
Admin is simple and he would need only two columns, username and password. User table at the beginning contains only these values:
username, password, admin, teacher, student, librarian
Columns admin, teacher, student, librarian are booleans which define does user have certain role. Admin would have admin to true and all other columns to false.
The problem is appearing when we introduce other columns which are specific to only one role. The we have these columns for user table:
id
username
password
admin
teacher
student
librarian
teacher_column1
teacher_column2
teacher_column3
student_column1
student_column2
student_column3
etc...
When user is created we need to fill a lot of columns with null values. If we create a teacher, all columns which are needed only for librarian and student are filled with nulls.
On a couple of places when people asked about this, they were recommended to do STI so they would end with something like this:
class User < ActiveRecord::Base
end
class Admin < User
end
class Teacher < User
end
class Student < User
end
This looks much better but would still introduce a lot of null values.
Other idea is to introduce 4 new tables for different user type details. Something like this:
User table:
id
username
password
admin
teacher
student
librarian
Teacher table:
user_id
teacher_column1
teacher_column2
teacher_column3
Student table:
user_id
username
password
student_column1
student_column2
student_column3
The same for Librarian and Admin. In the process of user creation after we check role, new row in specific table for that user would be created.
What do you think about this last approach? Cons and Pros?
Would this be a correct way in creating a system with multiple user roles? Thank you.
Don't use different columns for each permission.
Create a single table for Users with these columns:
username
password
user_type
user_type will be a value in %w{admin teacher student librarian} Then use single-table-inheritence like you mentioned in your post.
Create a table for Role:
name
Then create a table to tie roles to users:
role_id
user_id
Create a table for Permission:
name
Then create a table to tie permissions to roles:
permission_id
role_id
In the end you will have:
3 models with tables: User, Role, and Permission
4 models without tables, inherting from User: Admin, Teacher, Student, and Librarian
2 tables without models: users_roles and roles_permissions
Also, if there are many columns that are unique to every user-type, then I would recommend using different model+tables for each and making the user in Role polymorphic.
That way you can easily create new roles/permissions, modify the permissions of a particular role, and easily add/remove roles for a particular user.
I have a ER diagram made up and it consists of USER Table and within that it is set as
User ISA admin
and
User ISA member
Admin and Member tables are both child tables of USER.
I want two usertypes, m for member, a for admin.
ADMIN will have the option to change member to admin in admin panel
ADMIN table has: admin ID(PK) and user ID(FK)
MEMBER tableconsists of
memID (PK) userID (FK) signupDate lastlogin location, age, bio
USER table consists of
ID (PK) fname lname password usertype email
What I am trying to achieve is..
Guest must register via a form on registration age and must automatically be set as usertype (m) for member.
So because I have it as
USER ISA member
USER ISA admin
Which is the best way to have registration form? should it be for two tables (user and members) which wouldbe easiest way to achieve this in words? And also can it be explained how I can make sure it is auto set a usertype 'm' for member?
For telling admin vs user, you can just use one column (user_type). You can also use the DEFAULT in your table schema to handle that.
However, if you'd eventually like a more robust permission system, i'd recommend:
TABLE users - stores user info
TABLE permissions - With (e.g., permission_id, permission_name)
TABLE users_to_permissions - A table to link the two
That way, you can explicitly assign permissions for different things:
SELECT p.* FROM permissions p WHERE permission_id IN (SELECT DISTINCT permission_id FROM users_to_permissions u2p WHERE u2p.user_id = :user_id
You can also obviously use JOIN, or whatever fits your use case the best. When in doubt, prefer normalization and extensibility over a quick one-column solution.
SqlFiddle: http://sqlfiddle.com/#!2/bddba5/2
I have a database and normally users are the central object.
In database I have a tables roles and users in roles so I can give users different permissions on site.
But now I have one doubt.
I saw before one database with structure like this (User is in 1:1 relation to other tables):
User{UserId, Username, Email etc.}
Admin{UserId, some specific columns}
Child{UserId, some specific columns}
Admin{Parent, some specific columns}
and other tables are connected to user not through User table but through Admin, Child and admin.
Because now I design my database I have Users and user can be Admin, CompanyManager and Professor.
I wonder should I design table like I show above or just relied on roles?
What is advantage of the first approach?
And also in my business model User doesn't have to be CompanyManager or Professor so this is actually 1 to 0 or 1 design.
What is a good way to design database with scenario like this?
The advantage of having specific tables for certain types of users is to store information that is only relevant to that class of user.
In your example,
perhaps all users would have a manager - so the manager ID would go in the users column.
managers would have permissions to view certain information, so this would be handled via a role.
only professors would have a Subject, or the "HasTenure" property. So this information would go in a professors table. Using this approach, you avoid the need to have a "Subject" column in the users table, when it is only applicable to a certain subset of users. As such you avoid a functional dependency in the users table, and a violation of 3rd Normal Form.
I prefer this approach:
In this way, you can easily group Roles into categories and assign them to users.