How to handle multiple many to many relationships - php

I have a Laravel project in which there is likely to be multiple many to many relationships but I feel like I'm going around in circles in terms of the correct use of pivots tables.
The entities are as follows:
Centre: an office that is going to open soon and has information such
as name, location, postcode, opening date
Task: a task that must be completed before a centre can open, it has information such as name, department and centre type
Department: a department represents a key area such as IT, Marketing, Sales etc. Each task would have a reference to a department.
User: a user is a user of the system, they belong to a department and they can complete tasks.
Considerations:
A department has users, so users would have a department_id
A task has a department so would also have a department_id
A centre has departments so a pivot called something like centre_department with centre_id and department_id
A user has tasks assigned to them but only tasks that belong to a centre
The bottom statement is where I'm going in circles because:
A Task is to be assigned to a Centre which is fine as you could make a table like centre_task with centre_id and task id
A user has tasks assigned to them, however, is it okay to have a task_user table that has user_id and a centre_task_id, effectively a pivot table that uses another pivot table?
This is because a user can't be directly assigned to a task, they can only be assigned to a task within a centre as the tasks have a many to many relationship with centres.
If I were to assign a user just using task id, they would be assigned to that task in every related centre.
So, again is it okay to have a pivot table that uses another pivot table, or does this display an issue with the structure I have suggested?
Intended flow
A user creates a task, assigns it a department and a type so that this task is only relevant to a specific department and type of centre.
A user can assign a task within a centre to a user who is in the department that's relevant to the department of the task
The task in the centre would then have an assignee and a deadline
In theory I'd end up with a pivot table that has the following:
user_id
centre_task_id
deadline
date_completed
Essentially I just feel like I'm connecting too many pieces?

Laravel does the linking for you, simply use (in this case) morphToMany() & morphedByMany() in your Models to establish a relation between two tables. There is a very good Laracast and also a very good Documentation. I have linked this below:
Laracast Video very nice Explaination for Many-To-Many Relations
Laravel Documentation for Eloquent ORM In General

Related

how to avoid and prevent the duplication between two tables in the laravel migration?

I'm developing the CMS(College Management System) website using LARAVEL PHP framework. Now we need to build up to three types of consoles(Admin, Student, Employee). I'm stuck in the admin console that admin is able to perform the selections process. I have performed the task for the following.
Foreach series has many Users.
Foreach users have one Profile.
Foreach profile has many qualifications, experiences, attendances..
Students and Employees Record saved in the user's table.
Now we need to remove students and employees written in the eclipse shape because there is a duplication code in these two tables(student and employee), then we need to create the profiles table. Now remaining tables classes and courses(I have not yet decided what type of relation).
If you need any code from this example then I will add in the comments section.
In order to prevent duplication (if students and employees will always be the same entity) is to introduce a new model in the system called Person (or something similar). Then you will create additionally a PersonType enabling you to expand the model further if you ever need something more than student and employee.
DB schema would then have a relationship:
persons ---- M:1 ---- person_types
Where person_types would have:
ID Name
1 Student
2 Employee
This way you can reuse everything.

how can i make a relation between master calss and student in my platform

i want to create a platform by laravel 6 included classes students an masters
masters can put the student's scores and the students can see them in their profile...
there is a many to many relation between classes and masters and between student and classes too.
the masters an students are not seperated and all of them store in user table and determine by his role_id
my big issue is uploading of scores by masters... i am extremely confused
has any one any idea ?
What you might want to simplify things is an associative table of users, classes, and scores (I've drawn a diagram for you https://dbdiagram.io/d/5e9787f039d18f5553fdabb1). With this table, you can query pretty much all you could ever want.
Now all you need to do is configure privileges based on user role. A master can read from and write to all class_user_score entities where if there is a record of him being in a class, he can read and CRUD all class_user_score entities with the same classId. A student can only read class_user_score entities with his userId in them.
Unfortunately, I can't help you with the Laravel implementation (they also call an associative table a pivot table for some weird reason) since I'm more of a React, Nodejs type of guy, but I hope this at least helps you to reason about the problem.

laravel 5 OOP structure/architecture advice

I have a general question about how to implement the best practice of model structure for an application I'm building in Laravel 5.
So, at the moment I have things set up like this:
'user' model and table: id, email, password, admin level - this is really just the info for authenticating login.
'user-details' model and table: id, userID (foreign key for user table id field), name, address etc - all the other details
'lesson-type' model and table: id, teacherID (foreign key for user-details table id field), lesson-label etc - info about different types of lessons
At the moment I have a Teacher Controller in which I'm passing through to the view:
- The info from the User table
- The info from the User-details table
- A list of different lesson types for the teacher from the Lesson-type table
But I kind of feel that all this should be tied together with one separate Teacher model which would extend the User-details model (and probably which in turn should extend the User model), but wouldn't have it's own table associated with it, but all the info pertaining to either updates for the User-details or the Lesson-types table would be stored in those relevant tables. Would this be correct?
(I should also say that users may alternatively be parents rather than teachers, and so would I would have a separate Parents model for all the properties and so on associated with parents)
I would then pass only the Teacher model object into the view and thus gain access to all the teacher info such as personal details and array of lesson types.
As I'm typing, this is sounding more and more to me like the right way to go, but it would be great to get some advice.
1 - technical implementation: I guess in the Teacher model, I'd populate all the relevant teacher into class variables (Name, array of lessons etc) in the constructor?
2 - am I over complicating this structure by having both Users AND Users details tables?
3 - Does what I'm proposing make the most structural sense in Laravel?
4 - just another thought I've just had, should the teacherID in the lesson-type table actually refer to the User table rather than the User-detail table... so user-detail and lesson-type would both be direct children of the user table??
Very much obliged for any help :)
You shouldn't extend models like that unless there is a clear inheritance. From a logical standpoint, it just doesn't make any sense since you'll have to overwrite most of what is on the User model anyway. And what you don't overwrite will be incorrectly mapped to the database because they are 2 completely different tables. What you actually want to do is utilize Eloquent relationships.
For clarity, I am assuming this basic structure:
users - id
teachers - id, user_id
user_details - id, user_id
lesson_types - id, teacher_id
Those should be 4 completely different models all interconnected using the Model::belongsTo() method. So the Teacher model would be
class Teacher extends Model {
public $table = 'teachers';
public function user() {
return $this->belongsTo('App\User');
}
}
When you query for a teacher, you can do Teacher::with('user')->get(). That will return all records from the teachers table and on each instance of the Teacher model, you'll be able to call $teacher->user and get the User instance associated with that teacher. That is a full model, not just extra data, so you have access to everything on the User Model, which is generally the main reason for extending
For your list of questions:
I may be misunderstanding you, but this isn't how an ORM works. I'd suggest going back and reading through the Eloquent docs (if you're running 5.0, I suggest reading 5.1's docs since they are much, much better)
It will depend on who you ask, but I tend to think so. If the data is clearly related and there is no reason for it to be shared across record types (for example, I generally have an addresses table that all records reference instead of having 5 address fields repeated on multiple tables), I believe it should all be on one table. It just makes it more difficult to manage later on if you have it in separate tables.
There will be those who disagree and think that smaller scopes for each table are better and it will likely allow for quicker queries on extremely large datasets, but I don't think it's worth the extra trouble in the end
No, as I have explained above
The teacher_id column should reference the teachers table, assuming that lessons belong to teachers and cannot belong to just any user in the system. Using the ORM, you'll be able to do $lesson->teacher->user->userDetails to get that data
I really think you need to go back and read through the Eloquent docs. Your understanding of how Eloquent works and how it is meant to be used seems very basic and you are missing much of the finer details.
Basics
Relationships
Laracasts - Laravel Fundamentals - You would benefit from watching Lesses 7-9, 11, 14, and 21

How to keep data separate for businesses or groups of customers?

I've done quit a bit of programming with php/mysql on small scale personal projects. However I'm working on my first commercial app that is going to allow customers or businesses to log in and perform CRUD operations. I feel like a total noob asking this question but I have never had to do this before and cannot find any relevant information on the net.
Basically, I've created this app and have a role based system set up on my data base. The problem that I'm running into is how to separate and fetch data for the relevant businesses or groups.
I can't, for example, set my queries up like this: get all records from example table where user id = user id, because that will only return data for that user and not all of the other users that are related to that business. I need a way to get all records that where created by users of a particular business.
I'm thinking that maybe the business should have an id and I should form my queries like this: get all records from example where business id = business id. But I'm not even sure if that's a good approach.
Is there a best practice or a convention for this sort data storing/fetching and grouping?
Note:Security is a huge issue here because I'm storing legal data.
Also, I'm using the latest version of laravel 4 if that's any relevance.
I would like to hear peoples thoughts on this that have encountered this sort problem before and how they designed there database and queries to only get and store data related to that particular business.
Edit: I like to read and learn but cannot find any useful information on this topic - maybe I'm not using the correct search terms. So If you know of any good links pertaining to this topic, please post them too.
If I understand correctly, a business is defined within your system as a "group of users", and your whole system references data belonging to users as opposed to data belonging to a business. You are looking to reference data that belongs to all users who belong to a particular business. In this case, the best and most extensible way to do this would be to create two more tables to contain businesses and business-user relations.
For example, consider you have the following tables:
business => Defines a business entity
id (primary)
name
Entry: id=4, name=CompanyCorp
user => Defines each user in the system
id (primary)
name
Entry: id=1, name=Geoff
Entry: id=2, name=Jane
business_user => Links a user to a particular business
user_id (primary)
business_id (primary)
Entry: user_id=1, business_id=4
Entry: user_id=2, business_id=4
Basically, the business_user table defines relationships. For example, Geoff is related to CompanyCorp, so a row exists in the table that matches their id's together. This is called a relational database model, and is an important concept to understand in the world of database development. You can even allow a user to belong to multiple different companies.
To find all the names of users and their company's name, where their company's id = 4...
SELECT `user`.`name` as `username`, `business`.`name` as `businessname` FROM `business_user` LEFT JOIN `user` ON (`user`.`id` = `business_user`.`user_id`) LEFT JOIN `business` ON (`business`.`id` = `business_user`.`business_id`) WHERE `business_user`.`business_id` = 4;
Results would be:
username businessname
-> Geoff CompanyCorp
-> Jane CompanyCorp
I hope this helps!
===============================================================
Addendum regarding "cases" per your response in the comments.
You could create a new table for cases and then reference both business and user ids on separate columns in there, as the case would belong to both a user and a business, if that's all the functionality that you need.
Suppose though, exploring the idea of relational databases further, that you wanted multiple users to be assigned to a case, but you wanted one user to be elected as the "group leader", you could approach the problem as follows:
Create a table "case" to store the cases
Create a table "user_case" to store case-user relationships, just like in the business_user table.
Define the user_case table as follows:
user_case => Defines a user -> case relationship
user_id (primary)
case_id (primary)
role
Entry: user_id=1, case_id=1, role="leader"
Entry: user_id=2, case_id=1, role="subordinate"
You could even go further and define a table with definitions on what roles users can assume. Then, you might even change the user_case table to use a role_id instead which joins data from yet another role table.
It may sound like an ever-deepening schema of very small tables, but note that we've added an extra column to the user_case relational table. The bigger your application grows, the more your tables will grow laterally with more columns. Trust me, you do eventually stop adding new tables just for the sake of defining relations.
To give a brief example of how flexible this can be, with a role table, you could figure out all the roles that a given user (where user_id = 6) has by using a relatively short query like:
SELECT `role`.`name` FROM `role` RIGHT JOIN `user_case` ON (`user_case`.`role_id` = `role`.`id`) WHERE `user_case`.`user_id` = 6;
If you need more examples, please feel free to keep commenting.

Schema advice for minibus booking system

I'm developing with CakePHP 2.0 and MySQL.
I'm trying to create a minibus booking solution but I'm unsure if I'm following the right approach.
We have one minibus which we can book out. I'm not bothered about booking times overlapping at this stage. I've made a table for the minibus properties but I need to define the relationship between the minibus and the passengers.
Each minibus can have many (16) passengers.
A passenger can travel on more than one minibus (one today, one tomorrow etc).
Also I need to be able to set the type of passenger to either passenger or driver.
Will this need three tables? I was thinking:
Buses table (id, description)
Users table (id, firstName)
Passengers table (buses.id, users.id, passenger_type)
Any advice would be appreciated.
I think I would introduce a Trip table and assign the bus to an instance of a Trip. Then introduce a junction table to resolve the many-to-many relationship between Trips and Passengers.
Given that one minibus can service many passengers, and one passenger can ride on many minibus routes, then what you have is a many-to-many (m-to-n) relationship.
Therefore, you'll need three tables: one for Passenger, one for Minibus, and one that relates the first two via key associations:
Passenger_Minibus
------------------
PassengerID INT NOT NULL
MinibusID INT NOT NULL
It will look something like this:
One table to store capacity of the minibus. (CapacityId)
One table to store passenger information. (PassengerId, Name, address etc)
One table to store Minibus information. (MiniBusId, CapacityId, Make, Model, Year, color etc..)
One table for BookingInformation(BookingId, date, time, FromDestination, ToDestination etc)
One table for TripSchedule(TripId, BookingId, MinibusId)(Only if you have multiple buses per booking else you can add MiniBusId to BookingInformation table and get rid of this table)
One Link table to store TripId and PassengerId. (If you have only one minibus per booking, add BookingId instead of TripId)

Categories