Laravel 6.x relationship default value on first relation - php

I want to set a default value for the first relation element and after that another. For example:
Customer can have multiple addresses.
The addresses table has the column main_address.
When I create a customer and the first address for him, Laravel should then give the column main_address the value 1. The second should get the value 0 (if not specified different).
Is Laravel capable of doing this?
My creating prozess of a customer is the following:
$customer = \App\Customer::create(["data"]);
$customer->customerAddress()->create(["data"]);
$customer->contactPerson()->create(["data"]);
Can this prozess be improved?
The relations are both Many to one. A customer can have multiple contact persons and addresses.

You can do this
$customer = \App\Customer::create(["data"]);
$address = $customer->customerAddress()->create(["data"]);
$main_address_exists = $customer->customerAddress()->where('main_address', 1)->first();
if (!$main_address_exists) {
$address->main_address = 1;
$address->save();
}
So you first check whether this customer has an address with field main_address, 1 and if it doesn't have any such record it will make the last address as 1
OR
$customer = \App\Customer::create(["data"]);
$data_for_addresses = [
'main_address' => 0
];
$main_address_exists = $customer->customerAddress()->where('main_address', 1)->first();
if (!$main_address_exists) {
$data_for_addresses['main_address'] = 1;
}
$customer->customerAddress()->create($data_for_addresses);

Related

Laravel/Mysql: unable to set field to null

I am working on a laravel project and trying to duplicate a record in mysql db.
after replication I want to set a field value to null(appointment_status).
everything is working except the new record's value (appointment_status) is the same as the original record even tho I set it to null.
$newAppointment = $appointment->replicate();
//push to get the id for the cloned record
$newAppointment->push();
$newAppointment->duplicated_from_id = $appointment->id;
$newAppointment->appointment_status = null;
$newAppointment->save();
//updating the old appointment
$appointment->duplicated_to_id = $newAppointment->id;
$appointment->save();
Instead of whole code-block, try something like this:
// replicate as the new record with some different fields
$newAppointment = $appointment->replicate()->fill([
'duplicated_from_id' => $appointment->id,
'appointment_status' => null,
])->save();
// update some fields of initial original record
$appointment->update([
'duplicated_to_id' => $newAppointment->id,
]);
For more check out this.

Make custom Error validation rule

I'm trying to store student info in database id, name with course_1, course_2 from a form.
Same student can't register for same course again.
Students Table
id name
1 X
2 Y
Courses Table
id course_name
1 A
2 B
Student_courses Table
student_id courses_id
1 1
2 1
2 2
Student controller like this :
public function studentRegistration(Request $request)
{
$student = new Student();
$student->name = $request->Input(['student_name']);
$student->save();
$courses = array(
$request->Input(['course_1']),
$request->Input(['course_2']),
$request->Input(['course_3'])
);
foreach ($courses as $course)
{
$studentCourse = new StudentCourse();
$studentCourse->student_id = $student->id;
$studentCourse->course_id = $course;
$studentCourse->save();
}
}
How to make this custom validation with Laravel so same student can't take same course again?
Could you use an existing rule?
Validation rules:
'course_1' => 'different:course_2,course_3|...',
'course_2' => 'different:course_3|...',
I am not sure how exact the actual problem is to the example. If these fields are more dynamic than that, then a custom rule would make sense.
That is just for validating the input to be unique values for those fields. To check against the database is where the unique rule can come in:
'course_1' => [..., $uniqueRule = Rule::unique('student_courses', 'course_id')->where('student_id', $whoEverTheStudentToCheckAgainstIs)],
'course_2' => [..., $uniqueRule],
'course_3' => [$uniqueRule],
Could hide that behind a custom rule if you really needed to.

Laravel - How to pass different values for pivot data table in sync() function

My form sends a $request->assets that I am able to sync using the following:
$user->assets()->sync($request->assets === null ? [] : $syncData);
The complexity (not a problem) arises when I try to retrieve values from a serial number array that is sent back as $request->serialnumber
I have set up the serial numbers in such a way that the serial number array index corresponds to my id column in the assets table. E.g. if Mobile has a value of 1 in the database, it is located in $request->serialnumber[1], and for something that would have an id of 2, would be placed in $request->serialnumber[2] and so on.
I have done the following so far, in order to insert the correct serial numbers for the correct asset() relationship:
$serialData = [];
$pivotData = [];
$syncData = [];
//for every assigned asset, build an array of their serial numbers from the serial number array...
if(isset($request->assets))
{
for($i = 0; $i<count($request->assets);$i++)
$serialData[$i] = $request->serialnumber[$i];
}
//if some serials were set, use them for pivot data
if(count($serialData)>0)
{
$filledArray = array_fill_keys($serialData,"serialnumber");
$pivotData = array_flip($filledArray);
}
$syncData = array_combine($request->assets, $pivotData);
I know its a long drawn out way, so I'm wondering if there's an easier way to do this?

Symfony: Delete all the records in a table who have the id in the string in table's column

[Please note that I do not have code for this problem, I need code, I have tried to explain it the best way, and if you can help, it will be great]
so here is the deal, I have a field in the table named "order" for every user. The main job of the user is to bring other users to the system and when they bring a new user their id is sticked to (concated with) the referring user's id and stored in his "order field"
for eg.
user 'a' has id 31. 'a' brings in 'b' whose is assigned 32, now b's therefore b has the value: '31-32' stored in his 'order' field. simililarly if b brings in 'c' whose id is 35, the order for c will be: '31-32-35' and it goes so on.
Now when I delete 'a' I want ALL the users who have his id in their order fields, that is if i decide to delete 'a' in this above field, all the users should be deleted from he system too!
I want to do this via symfony controller, and I think that can be done by findAll() function in symfony but I have no clue how to use it.
Please help, I am really stuck!
I did by using a parent field in each table for the user:
and here is the code if such thing arises for someone:
<?php
$repo = $em->getRepository('SystemBundle:Distributor');
$temp = $slug;
$pd = $repo->findAll();
for ($i = 1; $i <= count($pd); $i++) {
$u = $repo->findOneBy(['parent' => $temp]);
if ($u) {
$temp = $u->getId();
$em->remove($u);
$em->flush();
} else {
break;
}
}
$dis = $repo->findOneBy(["id" => $slug]);
$em->remove($dis);
$em->flush();
Using for loop it was possible to do this

Import large number of records in laravel, each record having multiple relations

I have a case where user uploads a file containing large number of rows(let's say 1000). Each row contain information about a user.
This data is turned into PHP array with objects
E.g
$userArray = [{first_name: 'Peter', last_name:'Pan', email 'peter#example.org'},
{first_name: 'David', last_name:'Hasslehof', email 'david#example.org'}...]
Now for each row I would have to create
foreach ($usersArray as $user) {
$createdUser = User::create(array('email' => $user['email'], 'pin' => $user['id_code']));
$profile = Userprofile::create(array('first_name' => $user['first_name'], 'last_name' =>$user['last_name']));
$createdUser->profile()->associate($profile);
$createdUser->save();
$usergroup->addMember($createdUser);
}
This would mean that if I had 1000 rows, atleast 4000 queries, which is obviously too much. Is there a eloquent way to do this more elegantly?
I tried using querybuilder and insert first all profiles and then users but this did not work, because I dont know which profiles to retrieve(first_name and last_name are not unique fields) and therefore cannot link profile_id's to users that I would like to create.
I think you can use this this laravel library for import.
However, to import multiple relationships, i think there is no other way than use associate() or sync().
$model_object = new YourModelHere();
//your model id here
$model_object->id = $sheet->id;
//your model id fields
$model_object->field_1 = (int)$sheet->field_1;
$model_object->field_2 = (int)$sheet->field_2;
//related id of models heres
$id_of_related_1 = (int) $sheet->id_of_related_1 ;
$id_of_related_2 = (int) $sheet->id_of_related_2;
//in your Model.php the relation i.e. hasMany or Belongs to must be declared first.
$model_object->relationToModelOne()->associate(RelatedModelOne::find($id_of_related_));
$model_object->relationToModelTwo()->associate(RelatedModelTwo::find($id_of_related_2));
$model_object->save();

Categories