Create multiple model in laravel to belongsToMany - laravel

I have 2 models, Service and Schedule.
Schedule model has this relationship:
public function service() {
return $this->belongsToMany('App\Service','services_has_schedules','services_service_id','schedules_schedule_id);
}
Service model have this relationship:
public function schedule() {
return $this->belongsToMany('App\Schedule','services_has_schedules','services_service_id','schedules_schedule_id');
}
In frontend, this send me arrays day[] (day name), init[] (open hour), finit[] (close hour)
In the controller I want to know how to create multiple Schedule to sync() with Service

You can use syncWithoutDetaching to keep the existing records and add the new ones.
If you do not want to detach existing IDs, you may use the
syncWithoutDetaching method:
$user->roles()->syncWithoutDetaching([1, 2, 3]);
https://laravel.com/docs/5.6/eloquent-relationships

Related

Can we use an observer on the attach method in Laravel?

I would like to observe a pivot table in which, rows are created with an attach method in a specific model, is there a way to Observe that pivot table through the attach method that is responsible for creating rows?
after struggling some time, I came to answer my question,
so in order to observe a table whose rows are created by the attach method, we will need to do 3 things
1- we will need to create a model that extends
$Illuminate\Database\Eloquent\Relations\Pivot
2- Connect the model to the database table with this line:
protected $table = 'data_base_table_name';
3- use the method 'using' at the end of the BelongsToMany relationship in each model that is related to the pivot table
Example:
let's say we have a model called Student and another one called Group, we have also a pivot table called group_students that is filled with the attach method since we have a student BelongsToMany groups and Group BelongsToMany Students,
we will need to create a model named GroupStudent that extends
Illuminate\Database\Eloquent\Relations\Pivot
and link it to the group_students by adding the following line in the GroupStudent Class:
protected $table = 'group_student'
After that, we will need to add the using method The BelongsToMany relations in the Student Model and the Group Model like the following:
public function students()
{
return $this->BelongsToMany(Student::class)->using(GroupStudent::class);
}
and
public function groups()
{
return $this->belongsToMany(Group::class)->using(GroupStudent::class);
}
And here we go, now whenever I create a row in the group_students table through the attach method, this will be observed and the method created will be executed.

Creating a structure with Jobs, Events, Listeners, Queues in Laravel 8

I have a flow about that. I can solve the problem on paper. As a system admin, we have the following models: Clients, Departments, Users, Visitors, Calls, and Meetings.
Clients are our customers.
Departments are customers' departments.
Users have many roles, but we inspect the "Agent" role to define the
agent as a call center worker.
Visitors are those who want to meet
with an active agent by selecting a client and department.
Calls are a log table. If visitors can find the agent and send data to the
agent, I store data in the call table.
Meetings If the agent accepts the call, I store it in the meeting table and notify the
agent and visitor.
Client.php (Model)
public function users(){
return $this->hasMany(User::class);
}
public function departments(){
return $this->hasMany(Department::class);
}
Department.php (Model)
public function department_users(){
return $this->belongsToMany(User::class, 'department_user');
}
public function client(){
return $this->belongsToMany(Client::class, 'client_id');
}
User.php (Model)
public function departments(){
return $this->belongsToMany(Department::class, 'department_user');
}
Visitor.php (Model)
public function department(){
return $this->belongsTo(Department::class);
}
So as you can see, we define the relationships, and we want to do something like that:
Here is the flow...
The question is, how can I do that in Laravel 8?

Laravel Polymorphic get all models associated to a single model

I have an Attachment model which uses the morphs table and morphTo function. I have several models but the main ones include Client, Job, Project and Notes (which is also polymorphic) which can contain several Attachments.
A client is the top-level model. A Client has many Jobs. A Job has many Projects.
I am struggling with a single way to return all attachments of a client, including attachments of each Job, Project, and notes of each job/project under a client.
I currently am running several foreach loops and have a working way, but the queries on the page load range from 60-100 depending on the amount of jobs/projects/notes for each client. I run through each job to check if it has an attachment, if so, I loop through them. Then, I run through $job->notes->attachments and display those. From there, I dive into another foreach loop pulling all the job's projects, pulling the attachments from each project and then pulling all the notes and looping through that.
Is there a way within Laravel to get all of the Attachments that are somehow attached to a single Client without looping through the way I have? If not, is there a way I can optimize my loops so I don't have to request the attachments for each job/job's notes/project/project's notes?
I do this all the time. You just need a way to
"...get all of the Attachments that are somehow attached to a single
Client without looping through..."
You must consider custom joins, using Laravel Eloquent:
//client_id input here
$client_id = 10;
$att_from_client = Attachment::join('note', function ($join) {
$join->on('note.id', '=', 'attachment.object_id')
->where('attachment.object_type', 'App\\Note');
})
->join('project', 'project.id', '=', 'note.project_id')
->join('job', 'job.id', '=', 'project.job_id')
->join('client', 'client.id', '=', 'job.client_id')
->where('client.id', $client_id)
->get();
dd($att_from_client);
My advice is to use eloquent-has-many-deep. As example of you can do with that library you can look at the code of three models related with many to many:
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\Models\User')->withTimestamps();
}
public function permissions()
{
return $this->belongsToMany('App\Models\Permission')->withTimestamps();
}
}
class Permission extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function roles()
{
return $this->belongsToMany('App\Models\Role')->withTimestamps();
}
public function users()
{
return $this->hasManyDeep('App\Models\User', ['permission_role', 'App\Models\Role', 'role_user']);
}
}
class User extends Authenticatable
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function roles()
{
return $this->belongsToMany('App\Models\Role')->withTimestamps();
}
public function permissions()
{
return $this->hasManyDeep('App\Models\Permission', ['role_user', 'App\Models\Role', 'permission_role']);
}
}
With these relationships in place and 5 tables involved: users, role_user, roles, permission_role and permissions you can retrieve all the permissions of a User model with a call to $user->permissions, that resolves to only one query with all the joins needed.

Laravel Create multiple records in Pivot table

I'm trying to create a function in our Laravel 5.8 app that would add multiple records to a pivot table. At present we have the following setup;
Users
Training Courses
Users Training Courses (pivot table for the above relationships, with a few extra fields)
I want to be able to show all users in the database, then check their name, pick a training course and hit "Add" and it'll create a record in the pivot table for each user that was selected.
I can't figure out where to start with this - it seems like I need to have a "for each user selected, run the store function" loop in the controller, but I have no idea where to start.
I wasn't sure if there was an easy way to do this in eloquent or not. Is there a simple way to do this?
Eloquent does this automatically if you set up the relationships correctly and you don't have to worry about pivot tables.
class Users
{
public function trainingCourses()
{
return $this->hasMany(TrainingCourses::class);
}
}
class TrainingCourses
{
public function user()
{
return $this->belongsTo(User::class);
}
}
Then you can use the save() method to create the relationship. But I find it better to wrap this function inside a helper method that you can use throughout your code:
class Users
{
...
public function assignTrainingCourse(TrainingCourse $trainingCourse)
{
return $this->trainingCourses()->save($trainingCourse);
}
}
In your code, you could then do something as simple as this:
$user = User::find(1);
$trainingCourse = TrainingCourse::find(1);
$user->assignTrainingCourse($trainingCourse);
Building on this, suppose you have the following route to assign a training course, where it expects a trainingcourse_id in the request:
Route::post('/users/{user}/trainingcourses', 'UserTrainingCoursesController#store');
Thanks to route model binding, Laravel can inference the parent model (user) from the URL, and your controller might look like this:
// UserTrainingCoursesController.php
public function store(User $user)
{
$trainingCourse = TrainingCourse::find(request()->input('trainingcourse_id'));
$user->assignTrainingCourse($trainingCourse);
return back();
}
Of course, you'll want to put some validation in here, but this should get you started.

Laravel ORM relationship - manager-employee over the same table of users

I have a user_managers pivot table that gets both keys from the users table:
employer_user_id
employee_user_id
I believe users would have a many to many relationship as a user can be managed by more than 1 manager there will be users who manage 1 or more users, while other users (excluding those under them) would manage them while there will be users who don't manage at all and a User can have only 1 manager.
My first try at defining this was to build another model named Manager representing the user_managers pivot table, so in User model I wrote the following 2 functions:
public function managedBy()
{
return $this->belongsToMany('Manager', 'employer_user_id');
}
public function manages()
{
return $this->hasMany('Manager', 'employee_user_id', 'employer_user_id');
}
Does this make sense or do you know of a better way to implement this kind of structure?
If a user can have only 1 manager then you can define you relationship as one to many like
//User model
public function managedBy()
{
return $this->belongsTo(User::class, 'manager_id');
}
public function managees()
{
return $this->hasMany(User::class, 'manager_id');
}
you don't need to pass $id to your relationship definition.
For multiple managers, Yes you would need a many to many relationship by adding a junction/pivot table which i guess you already have user_managers, Now you need to define your relationships using belongsToMany for managers and mangees like
public function managers()
{
$this->belongsToMany(User::class, 'user_managers', 'employer_user_id')
}
public function managees()
{
$this->belongsToMany(User::class, 'user_managers', 'employee_user_id')
}

Resources