Why are multiple rows ('versions') saved with eloquent, when I only edit one - laravel

I use a versioning system to save multiple versions of a 'minor' (a model in my application). It contains quite a few fields, like name, goals, requirements, subject and many more. When I save a new version, or 'version 2', using eloquent, it also changes the other version.
I have tried multiple ways of saving the minor, like requesting the first one and updating it like below, or changing each individual item one-by-one.
Minor::limit(1)
->where("id", $id)
->where('version', $_POST['version'])
->first()
->update([
'name' => $_POST['name'],
'ects' => floatval($_POST['ects']),
'contact_hours' => intval($_POST['contact_hours']),
'education_type' => $_POST['education_type'],
'language' => $_POST['language'],
'subject' => Input::get('subject'),
'goals' => Input::get('goals'),
'requirements' => Input::get('requirements'),
]);
It should only save the selected version, but instead, it overwrites all versions of the minor with the same ID and saves them to the database.
How can I prevent this, or does anyone have an idea on how to fix this?

You can try using updateOrCreate method:
Minor::updateOrCreate([
'id' => $id,
'version' => $_POST['version']
],[
'name' => $_POST['name'],
'ects' => floatval($_POST['ects']),
'contact_hours' => intval($_POST['contact_hours']),
'education_type' => $_POST['education_type'],
'language' => $_POST['language'],
'subject' => Input::get('subject'),
'goals' => Input::get('goals'),
'requirements' => Input::get('requirements'),
]);

I still don't know why this happened or how to fix it using the same method. I have however found a way around it. I now update and save the minor with the ->update([...]) method build into eloquent.
Minor::where([["id", "139858"], ["version", Input::get('version')]])
->update([
'name' => Input::get('name'),
'ects' => Input::get('ects'),
'contact_hours' => Input::get('contact_hours'),
'education_type' => Input::get('education_type'),
'language' => Input::get('language'),
'subject' => Input::get('subject'),
'requirements' => Input::get('requirements'),
'goals' => Input::get('goals')
]);
This doesn't seem to alter the other versions. This is the only way I found to make it work, you can't make a variable of the object, change values and then save it. That would overwrite the other versions.

Related

How to assert array value but not strict?

How can we assert some of the array's property values which contain the expected object values?
My code below is working okay, but it checks all array property values. I want to ask if there's a way we can check only some of it.
$dataToBeTested = [
'name' => 'Johnny',
'address' => 'Somewhere',
'age' => 21,
'card_no' => 13331577121,
'rep_no' => 441546661,
'status' => 'in-progress',
'created_at' => '2022-07-31T10:05:27.011000Z',
'updated_at' => '2022-07-31T10:05:27.011000Z',
];
$expectedPropValue = [
'name' => 'Johnny',
'address' => 'Somewhere',
'age' => 21,
];
as expected it will return fail, since expectedPropValue has some missing properties.
$this->assertEquals($dataToBeTested, $expectedPropValue);
Goal is something like this,
$this->assertSomeOfIt($dataToBeTested, $expectedPropValue); // return true
You are looking for assertArraySubset, Which it's been deprecated with the newer version of PHPUnit. As mentioned here https://github.com/sebastianbergmann/phpunit/issues/3494. But you can always introduce your approach and use it for your project. Or you can also try this package https://packagist.org/packages/dms/phpunit-arraysubset-asserts. which gives you what you need
self::assertArraySubset($expectedSubset, $content, true);

Update a 1 Row 1 Column with Multiple Values

i've some problem with my code.
$id = DB::table('sn_project_details')->insertGetId([
'emp_name' => $request->emp_name,
'emp_id' => $request->emp_id,
'department' => $request->department,
'submit_date' => $request->submit_date,
'total_amount' => $request->total_amount,
'project_tittle' => $request->project_tittle,
'project_desc' => $request->project_desc,
'scope' => $request->scope,
'file' => $request->file
]);
//Update Table
\DB::table('sn_project_details')
->where('project_id', $id)
->update(['doc_ref' => "ID_",$request->scope,"_",$id]);
return redirect('/user')
I want to update column doc_ref with example value ID_Scope_220,
ID_ its fixed value. Scope from textbox scope. 220 from #emp_id.
but when i execute this code, update query not working properly.
can someone help? thx
use dot instead of comma
->update(['doc_ref' => "ID_".$request->scope."_".$emp_id]);

Optimize ApiResource

I'm having some problems when returning ApiResources because I can't figure out how to avoid overloading relationships.
In my UserResource, for example, I have:
<?php
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'role_id' => $this->role_id,
'role' => new RoleResource($this->whenLoaded('role')),
'group_ids' => $this->groups->pluck('id')->toArray(), // here are the problems
'groups' => GroupResource::collection($this->whenLoaded('groups')),
];
When loading single relationship id, all is ok, because $this->role_id is a property that is already in the Model. When using $this->whenLoaded('role') It will load the relationship conditionally, that's great!
The Problem: When loading many-to-many relationships, I can't set this 'conditional' eager load.
When I place:
'groups' => GroupResource::collection($this->whenLoaded('groups'))
It will load the ManyToMany Relation conditionally, cool!
BUT I would like to have array of ids with:
'group_ids' => $this->groups->pluck('id')->toArray()
However, this will execute the relation load ALWAYS

Laravel ignore unique validation on update

I have a Model which contains many foreign keys. One of those foreign keys must be a unique value.
My validation rules are the following ones:
$data['rules'] = [
'address' => 'required|string',
'buyer_id' => 'required|exists:buyers,id',
'buyer_name' => 'required|string',
'date' => 'required|date',
'email' => 'required|email',
'identification_photo' => 'required|string',
'invoice' => 'string|required',
'middleman_id' => 'nullable|exists:middlemen,id',
'price' => 'required|numeric|between:1,99999999999999999999999999.9999',
'property_id' => 'required|exists:properties,id|unique:reservations,property_id',
'purchase_receipt' => 'required|string',
'rfc' => array(
'required',
'regex:/^([A-Z,Ñ,&]{3,4}([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[A-Z|\d]{3})$/'
),
'tier_id' => 'nullable|exists:tiers,id',
'user_id' => 'required|exists:users,id',
];
The one that I have trouble is property_id. This must be unique in the current table which is reservations.
In order to ignore that validation when I make an update, I'm adding this line of code before calling the Validator:
$book['rules']['property_id'] .= ",{$item->property_id}";
And when I do a Log::info of all my rules, I got the following line: 'property_id' => 'required|exists:properties,id|unique:reservations,property_id,4',
But I keep receiving the error. Am I doing something wrong?
The error is on this line:
$book['rules']['property_id'] .= ",{$item->property_id}";
Instead of passing the id of the foreign key you want to ignore, you have to give the current model ID in order to ignore that validation for a specific item.
$book['rules']['property_id'] .= ",{$item->id}";
With this you tell that for your Model with id = x, ignore that specific validation. To understand it in a better way, you are telling that for this validation, ignore the validation of the property only for the record with id equals to the $item->id.
I think the line of code you are looking for is
'property_id' => 'required|exists:properties,id|unique:reservations,property_id,'.$request->id',
This ignores the current row you are updating while also validating your property_id

Updating a member's group interests using MailChimp API V3

I am running the following code (I've hidden ID's) to add/update a subscriber's interest groups in a MailChimp list:
$mailchimp->patch('lists/1234567/members/' . md5('test#test.com'), [
'status' => 'subscribed',
'merge_fields' => array(
'FNAME' => 'Ben',
'LNAME' => 'Sinclair',
),
'interests' => array(
'abcd1234' => true,
'defg6789' => true,
),
]);
The interests key is what I'm having issues with.
I presumed whatever you put in this key will overwrite what currently exists.
It doesn't seem to be the case. It only adds new interests but does not remove any if the ID's are not in the array. I am not getting any errors.
Does anyone know how to overwrite interest groups? Or if that's not possible, is there a way to remove interest groups?
For completion I wanted to add this answer so people stumbling upon this post can find a quick solution.
$mailchimp->patch('lists/1234567/members/' . md5('test#test.com'), [
'status' => 'subscribed',
'merge_fields' => array(
'FNAME' => 'Ben',
'LNAME' => 'Sinclair',
),
'interests' => array(
'abcd1234' => true, // Attached
'defg6789' => false, // Detached
)
]);
In this example the interest 'abcd1234' will be attached and the interest 'defg6789' will be detached.
Other interests that are not listed will remain on their original value.

Resources