Best way to update a lot of data with difference value? - laravel

I have a lot of data and each record have difference value. I try to loop insert/update data but it take time. Is it have better way to improve my code?
I don't want to delete all data before update.
$data = [
[ 'id' => 1, 'name' => 'A' ],
[ 'id' => 2, 'name' => 'B' ],
[ 'id' => 3, 'name' => 'C' ],
[ 'id' => 4, 'name' => 'D' ],
.
.
.
[ 'id' => 10000, 'name' => 'ZYX' ],
]
foreach ($data as $item) {
DB::table('my_table')->updateOrInsert(['id' => $item->id], $item);
}
Thank.

You can use upsert in Laravel 8.x or use this package: https://github.com/staudenmeir/laravel-upsert to use INSERT ON DUPLICATE
$data = [
[ 'id' => 1, 'name' => 'A' ],
[ 'id' => 2, 'name' => 'B' ],
[ 'id' => 3, 'name' => 'C' ],
[ 'id' => 4, 'name' => 'D' ],
.
.
.
[ 'id' => 10000, 'name' => 'ZYX' ],
];
DB::table('my_table')->upsert($data, 'id');

use laravel upsert method here
for example you want to update if exists or insert record if not exists
$data = [
[
'id' => 1
'name' => 'J.K. Rowling',
'author' => 'Harry Potter',
'quantity' => 15
],
[
'id' => 2
'name' => 'Cal Newport',
'author' => 'Deep Work',
'quantity' => 20
]
];
DB::table('books')->upsert($data, ['id'], ['quantity']);
1.The first argument consists of the values to insert or update.
2.The second argument lists the column(s) that uniquely identify records (id in our case) within the associated table.
3.The third and final argument is an array of columns that should be updated if a matching record already exists in the database. We want the quantity to be updated in our case.
for more detail read official docs upsert

Related

Remove duplicates in Laravel collection only if previous item is identical

I have a Laravel Collection of items:
[
[
'id' => 1,
'path' => '/',
'created_at' => '2020-05-20 20:12:00'
],
[
'id' => 2,
'path' => '/somewhere',
'created_at' => '2020-05-20 21:01:00'
],
[
'id' => 3,
'path' => '/somewhere',
'created_at' => '2020-05-20 21:21:00'
],
[
'id' => 4,
'path' => '/somewhere/else',
'created_at' => '2020-05-20 21:09:00'
],
[
'id' => 5,
'path' => '/somewhere/else',
'created_at' => '2020-05-20 21:10:00'
],
]
This is the raw data that would be found in the collection if I cast it to an array, but I need it to remain in collection format.
I need to remove any duplicates where the current item has the same path and is less than 5 minutes old compared to the previous item.
So in this case, item #4 would be removed leaving only #5, but items #2 and #3 would be kept even tho their paths are the same.
How would I do this?
Use the following namespace in your controller file:
use DateTime;
Use the following code in your controller file:
$collection = [
[
'id' => 1,
'path' => '/',
'created_at' => '2020-05-20 20:12:00'
],
[
'id' => 2,
'path' => '/somewhere',
'created_at' => '2020-05-20 21:01:00'
],
[
'id' => 3,
'path' => '/somewhere',
'created_at' => '2020-05-20 21:21:00'
],
[
'id' => 4,
'path' => '/somewhere/else',
'created_at' => '2020-05-20 21:09:00'
],
[
'id' => 5,
'path' => '/somewhere/else',
'created_at' => '2020-05-20 21:10:00'
],
];
$paths = [];
$time_count = [];
foreach ($collection as $key => $data) {
if (in_array($data['path'], $paths)) {
$arr_pos = array_search($data['path'], array_values($paths));
$datetime1 = new DateTime($data['created_at']);
$datetime2 = new DateTime($collection[$arr_pos]['created_at']);
$interval = $datetime1->diff($datetime2);
$mins = $interval->format('%i');
if ($mins < 5) {
unset($collection[$arr_pos]);
}
}
$paths[] = $data['path'];
}
This will return result:
array:4 [▼
0 => array:3 [▼
"id" => 1
"path" => "/"
"created_at" => "2020-05-20 20:12:00"
]
1 => array:3 [▼
"id" => 2
"path" => "/somewhere"
"created_at" => "2020-05-20 21:01:00"
]
2 => array:3 [▼
"id" => 3
"path" => "/somewhere"
"created_at" => "2020-05-20 21:21:00"
]
4 => array:3 [▼
"id" => 5
"path" => "/somewhere/else"
"created_at" => "2020-05-20 21:10:00"
]
]
I hope this works for you.

Laravel GraphQL UUID as ID does not work as expected

I'm using GraphQL in Laravel and I'm encountering this issue:
I've set id type to string but when I get my query through GraphQL, I get 553366 instead of 0553366c-6ebe-4340-8929-419ad46f4d15.
Here is my type definition:
public function fields(): array
{
return [
'id' => [
'type' => Type::string()
],
'name_en' => [
'type' => Type::string()
],
'name_fa' => [
'type' => Type::string()
],
'description' => [
'type' => Type::string()
],
'img_url' => [
'type' => Type::string()
],
'created_at' => [
'type' => Type::string()
],
'updated_at' => [
'type' => Type::string()
],
'SubBusinessFields' => [
'type' => Type::listOf(GraphQL::type('SubBusinessField'))
],
];
}
I've dd() the id and it was correct.
I've also tried id type instead of string but nothing changed.
How to fix this issue?
Just added this line to my Model and it got fixed!
public $incrementing = false;
It was weird that I couldn't find any similar problem anywhere else.

Laravel Resource Output

Quick question,
With Laravel I want to create a json output.
For this I use the laravel resource,
The standard resource looks like this
return [
'id' => 'test',
'first' => 'test',
'last' => 'test',
];
is there also a way to make the resource looks like something like this?
what would be the best way to accomplish this.
return [
'common' => [
'status' => 'succes',
'message' => 'succes',
],
'data' => [
'm_users' => [
'0' => [
'id' => '1',
'first' => 'test',
'last' => 'test',
],
'2' => [
'id' => '2',
'first' => 'test',
'last' => 'test',
],
'3' => [
'id' => '3',
'first' => 'test',
'last' => 'test',
],
],
],
];
Is there a way to changes the standard output that comes with the resource function?
Thank you.
You can additional data to your response like this.
return (new UsersResource($contacts))
->additional([
'status' => $status,
'message' => $message,
]);

How to remove element from multidimensional cakephp session

I am working on eCommerce website where is stored all cart product in session that is working perfectly.
Here are debug of cart session.
debug($this->request->getsession()->read('cart'));
[
(int) 1 => [
(int) 0 => [
'id' => (int) 1,
'picture' => '1_1.webp',
'sku' => 'TH447WA38OUMINDFAS',
'name' => 'The Vanca Multicoloured Printed Strappy Top',
'size' => 'S',
'price' => '480'
]
],
(int) 2 => [
(int) 0 => [
'id' => (int) 2,
'picture' => '2_1.webp',
'sku' => 'AL384WA86QOSINDFAS',
'name' => 'All About You Pink Embroidered Blouse',
'size' => 'S',
'price' => '1330'
]
],
(int) 3 => [
(int) 0 => [
'id' => (int) 3,
'picture' => '3_1.webp',
'sku' => 'RE367WA35NDKINDFAS',
'name' => 'Renka Comfortable Black Color Seamless Summer Tops For Women',
'size' => 'S',
'price' => '495'
]
]
]
Now i want to remove any row from cart but that is not working for me.
unset($this->request->getsession()->read('cart')[1]);
should be simply
$this->request->getSession()->delete('cart.1');
you can use dot notation when accessing session arrays
you could also read and delete the data in one command
$cart = $this->request->getSession()->consume('cart');
see the manual here and the API here and here

laravel array validation - work out depth for array

I am trying to validate recursive data which could have any number of levels e.g.
[
'name' => 'test',
'children' => [
[
'name' => 'test2'
],
[
'name' => 'test3',
'children' => [
'name' => 'test4'
]
],
[
'name' => 'test5',
'children' => [
'name' => 'test6'
'children' => [
'name' => 'test7'
]
]
]
]
]
In this example I would require the following rules to ensure that a name is specified at each level:
$rules = [
'name' => ['required'],
'children' => ['array'],
'children.*.name' => ['required'],
'children.*.children' => ['array'],
'children.*.children.*.name' => ['required'],
'children.*.children.*.children' => ['array'],
'children.*.children.*.children.*.name' => ['required'],
]
How could I dynamically generate the validation rules based on the data coming in?

Resources