cakePHP 3 save data in Many to Many relationship - cakephp-3.x

I have Employees and Complexes in a Many to many relationship.I have used the
bake console to generate models, controllers... for Employees and Complexes tables.
My questions is :
-Since I have in my BD The table "complexes_employees", do I have to bake also Model
and controller for this Table too or cakePHP is able to know that it contains the
two foreign keys of Employees and Complexes.
Second question :
-How can I save my data in this Three tables. for my app I have to save employees
per Complex .
// Employees Controller
public function addEmpPerComplex($id_complex){
$emp = $this->Employees->newEntity();
if ($this->request->is('post')) {
$employee = $this->Employees->patchEntity($employee, $this->request->data, ['associated'=>['Complexes._joinData']] );
//here I need to insert the record that contains the employee data in Employees Table
// then I need to insert in "complexes_employees" the ID of Complex sended in parametre of this function and the ID of the new Employee
Thanks for helping me

Do I have to bake also Model and controller for this Table?
No, CakePHP will use the abstract Table class. However, if you need extra information for this relationship, then you will need to create a join model. Check http://book.cakephp.org/3.0/en/orm/associations.html#using-the-through-option
How can I save my data in this Three tables?
As long as your data has the id of a related entity, it will automatically be saved both entity and relation:
$data = [
//employee data,
'complexes' => [
['id' => $id_complex]
]
]
$this->Employees->patchEntity($employee, $data, [
'associated' => ['Complexes']
]);
/*
Saves both the new Employee and the relation
(employeed id and complex id in complexes_employees)
*/
$this->Employees->save($employee);
For more information: http://book.cakephp.org/3.0/en/orm/saving-data.html#saving-belongstomany-associations

Related

Access model attributes in Laravel update query

I have an UPDATE query that I'm struggling with, basically want to access its column during update.
I have a users table (with existing data) with a column address where a string value is added. To make things cleaner I created a separate table locations to store all the addresses and set up foreignId('location_id') on the users table.
locations table is then filled by getting unique address values from users table.
Now I need to update the location_id of existing users.
**This is what I tried:**
$locations = Location::get(); // only about 100 results are there
User::query()
->whereNotNull('address')
->update([
'location_id' => $locations->firstWhere('street', DB::raw('address'))->id
]);
But the above query is not updating the column "location_id" on users table.
Model Relationships
// On Location Model
public function users()
{
return $this->hasMany(\App\Models\User::class);
}
// On User model
public function location()
{
return $this->belongsTo(\App\Models\Location::class);
}
You issue is that DB::raw('address') probably does not return anything so my suggestion is to update the whole query.
$locations = Location::all();
User::whereNotNull('address')->each(function($user){
$locations = $locations->where('name', $user->address)->pluck('id');
$user->attach($locations);
})
The above query will get all the locations first, then we get all the users who have an address and for each of those users we first find all the locations with that address, get the ids of those locations, add attach those locations to the user.

Laravel unique validation on update not working by passing id in validation

In my controller i am inserting data in three different table at a time.
I have put validation before inserting in some of the unique fields. But at the time of Update it says email already exists. I have searched a lot and got a solution which is working for everyone except for me by passing id in validation rule.
I have tried
$this->validate($request,[
'admission_no'=>"required|unique:students,admission_no,$id",
'student_email=>"required|unique:students,student_email,$id",
'guardian_email'=>"required|unique:student_parents,guardian_email,$id"
]);
$student = Student::find($id);
$student->admission_no = $request->admission_no;
$student->student_email = $request->student_email;
$student->save();
//parent model
$parent = StudentParent::where('student_id',$student->id)->first();
$parent->guardian_email = $request->guardian_email;
$parent->save();
It doesn't work this way i dont know why
also the main problem is StudentParent model is different how to pass id in validation for this model to unique update
Your students and student_parents table has different $id, So you need to pass student_parents table id on guardian_email validation :
$validatedData = $request->validate([
'admission_no'=>"required|unique:students, admission_no, $id", // expect students table id
'student_email'=>"required|unique:students, student_email, $id", // expect students table id
'guardian_email'=>"required|unique:student_parents, guardian_email, $student_parents_id" // pass student_parents table id here
]);
Hope this helps

laravel tables with relationship and insertion

I have 4 tables
Customers : with data of customers. this table hasMany(Refunds)
Refunds: with data of various request. this table belongsTo(Customers) AND belongsToMany(Services)
Services: with list of services. this table belongsToMany(Refunds)
Refunds-Services: bridge table for refunds and services
I have a form that must insert datas in the correct table.
public function storeRefunds(RefundsPost $request){
DB::beginTransaction();
$customers = Customers::create($request->all());
$refunds = $customers->refunds()->create([
'date_ref' => request('date_ref'),
'status_ref' => request('stato'),
]);
$tipo = $request->input('tipo', []);
$importo = $request->input('importo', []);
$refunds = Refunds::create($request->all());
for ($i=0; $i < count($tipo); $i++) {
if ($tipo[$i] != '') {
$refunds->services()->attach($tipo[$i], [
'services_id' => $tipo[$i],
'services_amount' => $importo[$i]
]);
}
}
return redirect("/");
}
with this code i can insert all datas in correct tables but i cannot find ID connection in the Refunds table. Two different ID are created in Refunds table. second created id in the Refunds table not connected to any customer (0) but connected to the list of services choosen.
How can i do?
Thx
You need to debug your code. First Refund creates in this line $refunds = $customers->refunds()->create and it's belongs to Customer, second Refund creates here : $refunds = Refunds::create($request->all()); and it's doesn't relate to any Customer, but relates to Service (you do this in for loop). By the way, your tipo input is not multiple (it should be with [] if you expects it can be more than one value) and for loop is senseless in this sutiation.
Delete one of Refunds::createmethods, bring your data to expected view and use createMany() method.
More info in Laravel docs : https://laravel.com/docs/7.x/eloquent-relationships#the-create-method

Invalid argument supplied for foreach() in laravel when use Eloquent: Relationships

I wanna get the class name of a user via the user ID. When I input the ID of a user so I will wanna get the class name. I have three tables such as users table, classes table, and class_users table. The class_users table is born from two users table and classes table.
A users table has an id, name, email, password.
A classes table has an id, class_code, class_name.
A class_users table has an id, class_id, user_id
And this problem relates to Eloquent Relationships.
Thank you for help.
My Route:
Route::get('/find_classes/{id}','StudentController#find_classes');
My Controller function:
public function find_classes($id)
{
$users = User::find($id);
foreach($users->classes as $class)
{
echo $class->name . '<br';
dd($class);
}
}
My User Model:
public function classes()
{
return $this->belongsTo('App\Classes','class_users','user_id','class_id');
}
Looks like you might have the wrong relationship set up on your User model. You have a one to many set up, but your DB is setup to handle a many to many. I suggest you change your User model relationship:
public function classes()
{
return $this->belongsToMany('App\Classes');
}
Note, you may need to name the FK on that relation, as I see you have class_id on the table, but your actual class is named 'Classes'. Check through your relationships to ensure this is explicit on the FK where it doesn't follow Laravel convention exactly.
With this relationship, your foreach loop should work. It would be a good idea for efficiency, as mare96 noted, to eager load the classes on the $users collection when you query:
$users = User::with('classes')->find($id);

Laravel and pivot table to relate different model

I'm wondering how, but it's bit confusing.
I have fine belongs to many relation between users and groups tables as well as appropriate models for all of that.
But i also have table students, where not all users are student so i students table i maintain user_id field.
My question would be: Can i use pivot table "group_user" for relations between student and group model, in students table i have "user_id" field? and how?
I tried something like
public function students()
{
return $this->belongsToMany('Student','group_user','group_id','user_id');
{
but i don't see the way how to tell eloquent not to take students.id but to take students.user_id???
Assuming these relations:
Subject belongsTo Group
Group belongsToMany User
User hasOne Student
you can easily do this:
$subject = Subject::find($someId);
// of course for multiple subject use eager loading:
// $subjects = Subject::with('group.users.student')->get();
$users = $subject->group->users; // related users
foreach ($users as $user)
{
$user->student; // null|student model
}

Resources