Creating a Whatsapp like model in Rails Framework. - mysql

Background: I am new to Rails and I have gone through Michael Hartl Ruby on Rails tutorial.
I have read Agile Web Development with Rails 5.
So for practice I was trying to design WhatsApp like framework and got stuck while creating User and Group model.
Problem: I have tried different user and group model relationship and each one is failing for some reason.I have tried few paths so I will enlist them below.I don't need code, just a correct database relationship between User,Admin,Group,Participants.Also we should be able to add relationship through UI.
We have two tables User and Group.Admin belongs_to Group.Group has_many Admins. Group has_many partcipants. Participant belongs_to group.Participant is a new table having user_id and group_id.
We have three tables User,Group and Admin_Participant.Admin_Participant table contains admin_of column and participant_of column and one user_id column.admin_of and participant_of will contain group_ids.
Similar to first but we have a different table for admin which contains user_id , group_id, boolean table for is_admin.
Group is reference to User and admin column is boolean.Participant is added to User table and is also a boolean.
One more Thing As soon as a user creates group he is assigned to be admin of that group.Remember the restrictions of participants.

3 tables ( and their models ) should suffice.
User
has many participants
has many groups through participants
Group
attribute: created_by ( user id )
has many participants
has many users through participant
Participant
belongs to group
belongs to user
attribute admin
The above should work provided that an admin is also a participant.
If there are admins who are not participants, then a extra column for 'participating', or 'non-participant' is required.
There is no need for an admin table unless the admin has other attributes.
In case you haven't, it's good to go through the guide

So this might be too far down the rabbit hole but I see only 2 tables, User and Groups. A user can be a admin and/or participant. The relationship between user and group would probably be has_or_belongs_to_many as a user can belong to many groups and a group can have many users. Further, to accomplish the user/admin/participant distinction, I might even subclass it with STI(single table inheritance) instead of using booleans to determine if someone is an admin or not.

as you specified you need a relationship model not code.
i think i can help.
you might have to reshape your whole database, but if i were you, i would do it like ...
User - name , user_id , mob_no , groups (before someone need to log in , my app would send em the code through which they can verify that they are the owner of that mob no. //we would not discuss that in detail/// )
######## has_many: groups
group - name , users , admin(boolean) (i made a different column for admin, the users column stores the user_id of the user , when someone creates a group he automatically becomes the admin , so admin column becomes true for that user id.. and later that admin can make other admin as well...[if you have problem implementing this i would suggest opening up michael hartl's book and read how he made an example user an admin and that admin could delete other users , that will help])
########## belongs_to: user
i do not understand how you would implement the admin of a group to add users to group,
so in this case i would like to suggest the following -
$ if the user has followed another user he can add that user to the group...
$ or a facebook like system " where user gets users invite to the group ,and later its upon him to decide whether he want to join or not.
% pls comment and lemme know if this helps. and any other suggestion.

Related

Do I need more than my current 3 tables in order to create the relationships explained in my post?

I'm trying to create a clone of a very popular application called Discord which allows people to communicate over voice, video, and text.
Discord allows every user to create their own servers and invite people to them. In order to allow users to create servers, I first created 2 tables - users and servers
Users table:
id, username, password
And
Servers table:
id, name, image, userId
So the relationship between these 2 tables is that a user can create and have many servers and a server belongs to a user. So far, so good.
Once a server is created, users can join the server as members of that server. A user can join as many servers as he wants and a server can have many members. I achieved this by creating a server_users junction table and a many-to-many relationship between users and servers:
Server_Users table:
id, userId, serverId
This works fine, however, I'm not sure if the logic behind the many-to-many relationship between users and servers is sound. To me it seems like I'm applying 2 relationships between users and servers and I don't know if this is correct. Maybe I need more tables to make the relationships clear?
User has many servers and a server belongs to a user ( Because a user is the owner/creator of a server, and the server belongs to only 1 user - his creator )
Server has many users and users have many servers ( As in every server can have many members and every member can be a part of many servers )
I think it's good design, almost a textbook example. The goal is that the tables are in normal form, which is the case here.
An alternate design also with three tables, if you would like to "merge" the two relationships, is to also use Server_Users to store the user who owns the server, marked as such with a boolean column. However, I think it is more efficient how you did it with a foreign key (userId), as you will only need one join for the 1-to-N relationship.
I would also add that the design of the table is not only motivated by getting this right "theoretically", but also by your use case. Picking a design depends on the kinds of queries that you will run against the database. If you list all users on a server including the owner, but never the owner alone, then the alternate approach may be faster.
Another aspect is integrity constraints: do you require that the owner of the server is also a member of that server, or is it fully independent? This also influences the design.
An alternative in the context of large quantities of data that do not get updated often, is to denormalize everything, by nesting the users (replicated) inside the server tuples.
I think your approaches are good.
As discribed before it's depending on your use cases or future functions.
In my opinion you have this possibilities:
Possibility 1
user
id
username
password
server
id
name
image
userId
adminId (references user id of admin/owner/creator)
user_server
id
userId
serverId
Possibility 2
user
id
username
password
server
id
name
image
userId
user_server
id
userId
serverId
admin (null if not an admin and true if an admin/owner/creator)
Possibility 3
user
id
username
password
server
id
name
image
userId
roleId (1=normal user, 2=admin,3=moderator)
user_server
id
userId
serverId
role
id
rolename
With possibility 1 you are limited to one owner of a server.
With possibility 2 you could add a "admin flag" to each user wich is allowed to manage the server. (like in chat groups of a messanger where exists multiple group admins)
With possibility 3 you could add a system to manage the rights of the corresponding users.

How to Manage Guest Users with Php and SQL

I am using PHP , MySQL for Handling My site. I have a user table called user_table containing user_id PRIMARY and Now user can chat with other user. For that I am using a table called message_table. this table contains essential fields like msg_id , sender_id , reciver_id , replay_id etc. this works very fine.But I need to handle also guest users[Not registered] with this chat. how can I handle them. I inserted the guset_id as the mixture of entering time and his name to a table called guest_table. Now I can use this guest_table like user_table. Is that a good idea ?
But I need to handle also guest users[Not registered] with this chat.
These guests look to me like a special sort of user. I suggest you handle them as if they were users. You may wish to put a column called something like is_guest in your user table, and set it to 1 when you know the user is a guest.
Keeping a separate table, parallel to the user table, for your guests is NOT a good idea. It will greatly complicate your queries, especially when a person in your user table communicates with a person in your guest table.
Instead, put everybody in the user table, guests and registered users alike.
A nice little benefit: if you convert a guest to a registered user, all you have to do is flip the is_guest flag and let them specify their own username and other data. They get to keep their history.

sql - normalize user table with it groups but both can login

Hi currently i have 3 tables:
users
|id|name|email|password|last_login|created_at|
user_groups
|user_id|group_id
groups
|group_id|name|email|password|last_login|created_at|
Group can login so it when i can view statistics for specific all it users, that's why i put email and password too.
the problem is users and groups got almost everything same. 1 group can contain many users.
Is there anyway to make this more normalize and user still have their specific groups?
I would just use the user authentication to detect whether the user belongs to any group or not. That way you don't need all these extra fields for the group.
If you only want one specific user to be able to look at the group statistics you could add an admin_id to the user_groups table (which would relate to a user id)

Efficient way to handle user roles

I am working on one portal where will be few user roles. I have been wondering what is the best way to handle them. I have created separated tables for users and clients, but clients will want the functionality as users and users can become clients easy too.
I also don't want to make many joints, so what I as thinking is this:
I will have 4 different user roles (at least for now) as follow:
user
client
reviewer
admin
I will assing "id" to each role. At the same time I will keep table in mysql with these roles. It will be something like:
1 - admin
2 - reviewer
3 - client
4 - user
This table will be used only upon creation of user, to get the code of user "permissions". So Let's say that there will be a guy who is a user and reviewer. His role would be 24.
login password email role created
----------------------------------------------------------
guy password guy#gmail.com 24 2012-12-08 23:12:30
I think this could work pretty well, but still want to ask if you guys think this is good and effective solution.
Thanks
The other way to do this would be to have a many to many USER_ROLE table where for your example guy would have the following entires.
login role
guy 2
guy 4
I generally prefer this method of tracking roles. A join against this table in a situation like this should be fast and painless, especially if you move to using a user_id instead of a login, and index appropriately.
What you're defining is a Role Based Access Control System (I would suggest looking up resources on this). An RBAC system will have a separate table for users and another table for roles. There will be a many to many relationship between users and roles. Also, you will connect a permissions table to roles in another many to many relationship. The image attached represents how to implement this system:RBAC SYSTEM IN MYSQL
A similar question was asked before: How to design a hierarchical role based access control system

Database modeling

My question is about modeling a particular situation:
In my model I have tables: User, Offices and Partners.
The system has different user profiles: users of Office (counselors, principals, assistants), users for Partners (Institutions,..), admin users.
What is the best way to model the relationship between office users and partner users if:
- The users are unique (two users should have the same login - should be in only 1 table)
- An office user is associated to only one office
- A partner user is associated only with a partner.
It should be a table for office users and one for partners users?
A many to many relationships in this case would not work, right?
Thanks for your help.
You have not provided enough definition re Partners and Offices, so those parts of the model are not yet complete, but I think the main question you are asking is answered in this ▶Data Model◀. As I understand it:
User (login, UserName is unique, and you do not want that to be unclear)
Users are exclusively (that is the X in the half-circle) Office/Partner/Administrator
that requires a Supertype-Subtype structure. The cardinality is 1::0-1
Users belong to (?) an Office or a Partner, exclusively.
That may be OfficeType or OfficeTitle.
If you define that last item a bit more, I can finish the model.
Readers who are unfamiliar with the Standard for Modelling Relational Databases may find the ▶IDEF1X Notation◀ helpful.
Assuming this model will never change I would add a field to the users to determine where they belong. You could put an enum named user_type with possible values of 'office', 'partner', or 'admin'.. And then you could put in columns of office_id, and partner_id so you could join the tables as needed.
I think the best route would be to go with an account group structure, where you use an association table to determine who's in what group...
group
id | name
group_assoc
group_id | account_id