Laravel upsert createing duplicate records - php

$responsible_users = collect($request->responsible_users)->map(fn ($user_id) => new OrganizationElementUser(['user_id' => $user_id, 'organization_element_id' => $organization_element_id, 'type' => DeviceAuthAndHierarchyElementRole::RESPONSIBLE_ROLE]));
$subordinate_users = collect($request->subordinate_users)->map(fn ($user_id) => new OrganizationElementUser(['user_id' => $user_id, 'organization_element_id' => $organization_element_id, 'type' => DeviceAuthAndHierarchyElementRole::DIRECT_SUBORDINATE_ROLE]));
$internal_users = $responsible_users->merge($subordinate_users)->toArray();
OrganizationElementUser::upsert($internal_users, ['user_id', 'organization_element_id', 'type'], ['user_id', 'organization_element_id', 'type']);
Why is my upsert creating duplicate records?
My user_id, organization_element_id, type fields can individually be duplicate but all 3 of them combined creates a unique record
ex. of what I want is:
user_id == 1 && organization_element_id == 2 && type == 'test'
//ignore if true otherwise insert

You can use UpdateOrCreate method. Documentation here.
User::updateOrCreate([
'user_id' => $user_id,
'organization_element_id' => 2,
'type' => 'test'], //if everything matches with these conditions, the row will get updated, otherwise, it will be inserted. It is like the where clause.
['column_xyz' => $request->new_string],
);

Related

Laravel prevent data duplicate in database

I want to prevent data duplicate in database when user applies a job post multiple times.
I tried firstOrNew() like...
$apply = Applies::firstOrNew(
['user_id' => Auth::id()],
['posts_id' => request('id')]);
$apply->save();
But this time user can't apply other posts anymore .
Edit 1
I tried it but doesn't do anything.
$apply = Applies::firstOrNew(
['user_id' => Auth::id()] && ['posts_id' => request('id')],
['user_id' => request(Auth::id())],
['posts_id' => request('id')]);
$apply->save();
The first array is the "attributes", the where conditions for the look up. You would need to have the user_id and post_id in that array:
Applies::firstOrNew([
'user_id' => ...,
'post_id' => ...,
]);
This will cause it to search for that combination and only if it can't find it will it create a new (non-existing) model instance and fill it with those "attributes".

How to add value into existing array without replacing exists array data? [duplicate]

Here I used updateOrCreate method to post data but when I use this method old data replaced by new data but I want to add new data without updating or replacing exists data.
here is the code for insert data
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id], // match the row based on this array
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => json_encode($seat),
'price' => $request->price,
'profile' => 'pending',
]
);
I solved myself, I stored old data into $extSeat then merge with new data, I don't know the logic is correct or wrong but works
$extSeat = DB::table('bookings')->select('seat')->first();
$extSeat = explode(",", $extSeat->seat);
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id],// row to test if schedule id matches existing schedule id
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => implode(",", array_merge($seat,$extSeat )),
'price' => $request->price,
'profile' => 'pending',
]);

How to insert new data into exists row without replace exists data in laravel?

Here I used updateOrCreate method to post data but when I use this method old data replaced by new data but I want to add new data without updating or replacing exists data.
here is the code for insert data
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id], // match the row based on this array
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => json_encode($seat),
'price' => $request->price,
'profile' => 'pending',
]
);
I solved myself, I stored old data into $extSeat then merge with new data, I don't know the logic is correct or wrong but works
$extSeat = DB::table('bookings')->select('seat')->first();
$extSeat = explode(",", $extSeat->seat);
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id],// row to test if schedule id matches existing schedule id
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => implode(",", array_merge($seat,$extSeat )),
'price' => $request->price,
'profile' => 'pending',
]);

Laravel 5.4 current id insert eloquent

When register at Laravel using eloquent, my PK field at table users is userid [auto increment] I want to insert the current id at the same time when I run the User::create(); to different field (create_by [int]) so the create_by field will be filled with the same value as the primary key field userid, like this code:
User::Create([
'user_email' => $data['user_email'],
'user_password' => bcrypt($data['user_password']),
'first_name' => 'John',
'last_name' => 'Doe',
'department_id' => 1,
'user_level' => 1,
'create_date' => Carbon::now('Asia/Jakarta'),
'create_by' => // value same as userid the PK
])
How to get the current id to be used in different field?
I actually try some trick to get the id like this:
User::insertGetId([
'user_email' => $data['user_email'],
'user_password' => bcrypt($data['user_password']),
'first_name' => 'John',
'last_name' => 'Doe',
'department_id' => 1,
'user_level' => 1,
'create_date' => Carbon::now('Asia/Jakarta')
])
It was good to return the inserted id, but my expectation is I want to save the current id to the create_by field at the same time user_id was inserted, not after the data was saved.
You can try
$user = User::create([...]);
$user->create_by = $user->id;
$user->update();
Update
You can get the last user in the database. But be aware this is not 100% safe.
$lastUser = User::orderBy('id', 'desc')->first();
$user = User::create([
...
'create_by' => $lastUser->id + 1
]);
Might be its not a good way but it will work fine Try it
I am assuming db fields please review query as desired. Its a hint to work
1st need to get max id of user as
$users = User::whereRaw('id = (select max(`userid`) from users)')->first();
$create_by= $users->id+1;
//dd($create_by);
//die;
If you remove commented code it will give you next id now pass this variable as
'create_by' => $create_by,
You can do it by:
$user_save_obj = User::Create([
'user_email' => $data['user_email'],
'user_password' => bcrypt($data['user_password']),
'first_name' => 'John',
'last_name' => 'Doe',
'department_id' => 1,
'user_level' => 1,
'create_date' => Carbon::now('Asia/Jakarta')
])
$last_inserted_id = $user_save_obj->id;
$user_update_obj = User::find($last_inserted_id);
$user_update_obj->created_by = $last_inserted_id;
$user_update_obj->save();

Cakephp - saveAll and beforeSave

Since CakePHP is updated to 2.3.5, I have problem to save data.
I don't want to save datas who contains no price.
My method beforeSave in my model looks like this :
public function beforeSave($options = array()){
if(empty($this->data['MyModel']['price'])){
unset($this->data['MyModel']);
}
return true;
}
Since my update, i've found this in /lib/Model/Model.php (l. 1751)
if ($success && $count === 0) {
$success = false;
}
If i comment this 3 lines my problem is solved. Do you know a method in my beforeSave who don't block my saving ?
If i use data validation, all my datas are not saved with my saveAll.
Exemple model "Option" validator:
public $validate = array(
'prix' => array(
'rule' => 'notEmpty'
)
);
Exemple datas to save :
array(
'Commande' => array(
'nature_commande' => '0',
'base_id' => '1',
'nom' => 'Test',
'chef_id' => '531',
),
'Option' => array(
(int) 0 => array(
'prix' => '5456'
),
(int) 1 => array(
'prix' => '45645'
),
(int) 3 => array(
'prix' => ''
)
)
saveAll in my Controller "Commande" (return false):
debug($this->Commande->saveAll($this->request->data, array('validate' => 'first')));
I would like my datas be saved out of the last row in my Model "Options" => 3.
I can use foreach in my controler to delete the blank row but can i make it better ?
Have you thought about using CakePHP's built-in data validation? This would allow you to specify that you don't want to save unless the 'price' is a certain amount, greater than zero, between a range...etc etc etc.
Basically, you set up rules for your fields, and any time you try to save a row, it makes sure each field passes whatever validation you set up.
It has a ton of validation types including valid email, number ranges, phone numbers, regex and more.

Categories