Laravel Many to Many (3 and 3+ Models) Design Questions - laravel

I have got three models
Contacts Model
Contact Roles Model
Project Model
Set up;
contacts can belong to multiple projects. (Many to Many)
each project has its own contact roles created by user. (One to Many - Roles are specific to projects)
Within selected project, a contact can be assigned to multiple roles (Many to many)
Tricky part is I have categories for roles model, when user is creating the role, they select a category for that role from a dropdown(from a db, total of 7 predefined categories).
Then what I try to do and have issue with understanding;
1.What is the best way to display all contacts with given roles on that specific project?
I can easily get $project->contacts() //this gives me all contacts within that projectbut I need to one step further, where I can get contacts with their roles.
2.Furthermore, how would I display all contacts that are part of that selected category for that project?
3.Should i be using a different connection between my models other than many to many, like has many through ?

Assumption - with
display
you actually mean retrieve with eloquent.
Word of advice - READ THE DOCS! Laravel has great and easy to understand documentation.
https://laravel.com/docs/5.7/eloquent-relationships#eager-loading
1) I can easily get $project->contacts() //this gives me all contacts within that projectbut I need to one step further, where I can get contacts with their roles.
Nested eager loading:
$project = Project::with('contacts.roles')->find($id);
2) Furthermore, how would I display all contacts that are part of that selected category for that project?
Constraining eager loads and querying relationship existance:
$project = Project::with(['contacts', function($q) use ($categoryId) {
$q->with('roles')->whereHas(['category' => function($q2) use ($categoryId) {
$q2->whereId($categoryId);
});
}]);
3.Should i be using a different connection between my models other than many to many, like has many through ?
Structure looks fine to me.

Related

Laravel many to many relation attach to multiple models

I have many to many relation with pivot table. I know that I can use detach, attach and sync on a model , but is there a way to do this for multiple models with one call ?
For example I have Category and Product models and I want to assign same categories to multiple products.

Laravel: Table structure for multiple users types, polymorphic relationships

In my site (api using laravel 5.6 and laravel passport) I have two types of users (Teachers and Students), in the future there will be more. The teacher and student entities are very different, meaning that if I keep them all in one table, the table will be long and many fields will have a null value. Right now I have one Users table with common fields and two other tables (Teachers and Students) to which I have setup a polymorphic relationship from user. My question is if this is a good approach, or if there are other ways to handle this more elegantly?
I would create 1 table for Teachers and 1 table for Students and not use the Users table/model. This way you can keep them completely separate and not worry about adding more types of users in the future. Continually trying to fit new users into your existing Users model, which would be shared, is a headache. I made this same mistake when I started and eventually had to rework the project.
There are plenty of guides for Laravel multi-auth / multi-user online.
Here are a couple to help you get started:
https://medium.com/hello-laravel/multiple-authentication-system-laravel-5-4-ac94c759638a
https://www.codementor.io/okoroaforchukwuemeka/9-tips-to-set-up-multiple-authentication-in-laravel-ak3gtwjvt
Also, there are cases where it makes sense to use the User model for multiple types of users. For example, you may have multiple roles for a user where most/all of the fields are the same (not your scenario). In this case, you can assign a 'role' to each User and the check the roles for actions (e.g. add middleware to prevent roles from accessing various routes). Here is an example:
https://medium.com/#ezp127/laravel-5-4-native-user-authentication-role-authorization-3dbae4049c8a
Since you said the teacher and student entities are very different, you should keep them separate.

Laravel get all related models for multiple models

I have a users table and a groups table.
I have set up a many to many users/groups relations.
When I run
$users = User::where("id",'=',6)->first()->groups;
,I get the right group.
But I will have cases where my queries will take in an array of users.
How do I get all the groups of all those users using laravel relationships ?
eMAD's suggestion does not work because Laravel only allows relationship functions to be execute on objects and not array of objects. What you want harvey is a concept called eager loading.
$users = User::whereIn('id', [6, 7, 8])->with('groups')->get();
By using this code, you will be able to access $user->groups->someInfo in your code. Happy coding

Three way relationship in Laravel

having a brain failure with a relationship between three objects, hoping someone can help me out.
I have four models: Team, User, ProjectType and Project
Team has many User, has many ProjectType
User belongs to many Team, has many ProjectType
ProjectType belongs to manyUser, belongs to many Team, has many Project
Project belongs to ProjectType
As a single user can belong to many teams, I want to request the ProjectTypes that a User has access to, but only within the Team they are currently logged in with. It may be the case that a User has access to project types across multiple teams, but will only be logged in to one team at any time, so I need just that subset.
I'm hoping this structure makes sense, but I'm struggling to get access to the data I want easily
So I'd like to do $user->projectTypes and get all project types for that user, but only the subset of the team they're currently logged in with.
Equally, once I've got that, I want to be able to get $user->projectTypes->projects within that set.
I'd like to do this whilst maintaining all of the nice relationship methods I get with Laravel, but am struggling to setup the data structure to support this, and get the data in turn.
Worth adding I'm using Laravel 4.2, but am not desparately tied to it, and can upgrade to 5.x if necessary to get this functionality.
Once you've defined the relationships as you've described, you can access the ProjectTypes that belong to a User, that also belong to a certain Team (in your case $teamid should be the id of the Team that the User is currently logged in to) like so:
$projectTypes = $user->projectTypes()->where('team_id', $teamid)->get();
To easily access a collection of all Projects that belong to all ProjectTypes that belong to a User, you would first define the HasManyThrough relationship like so:
class User extends Eloquent {
public function projects()
{
return $this->hasManyThrough('Project', 'ProjectType');
}
}
Then you can access that collection like so:
$projects = $user->projects;
And finally, to access the Projects that belong to the ProjectTypes that belong to a User, that also belong to a certain Team (i.e. what it seems you're looking for), you can use lists() to get a list of relevant ProjectType ids, then whereIn() to filter for those within that list:
$projectTypeIds = $user->projectTypes()->where('team_id', $teamid)->lists('id');
$projects = $user->projects()->whereIn('projecttype_id', $projectTypeIds)->get();

Magento save many to many models

I have created a custom module with 3 models (student, room, studentroom).
The studentroom is used to store the relation between student & room (manytomany).
I have maked the form + grid to the students and rooms and i can create both of them. i want now to add a multiselect in the student form to select the rooms (until now its ok). When i save or edit my student how can i save or display also the association in studentroom.
Anyone has an idea ? A module with the same functionalities ?
Thx for advance
Magento's ORM has no built-in methods for the sort of one to many and many to many relationships you're describing above. As such, it's up to each individual developer to implement their own save methods that (before or after calling parent::save()) handle any extra relationships an object might have.

Resources