UpdateOrCreate with model instance - php

I am using PHP 7.1.33 and Laravel Framework 5.8.36.
I am getting receiving data from a database row-by-row and I am creating a model using updateOrCreate() like the following:
foreach ($arr as $v) {
$product = new Product();
$product->name = $v['name'];
$product->url = $v['url'];
$product->price = $v['price'];
// save
$matchThese = ['name' => $name, 'url' => $url];
$product->updateOrCreate($matchThese);
}
However, nothing gets created.
Any suggestions what I am doing wrong?
I appreciate your replies!

updateOrCreate takes 2 parameters ($attributes, $values).
$attributes is an array containing key-value pairs which will basically be used for where clauses i.e. it will check the database for the attributes passed in this array.
$values is an array containing key-value pairs of what to update in the database.
If it can't find a row in the database matching the first array it will combine the values in the arrays to create a new row.
To achieve what you're after you can do:
Product::updateOrCreate(
['name' => $v['name'], 'url' => $v['url']],
['price' => $v['price']]
);

Try this way
Product::updateOrCreate(
['name' => $name, 'url' => $url],
['price' => v['price']],
)
First parameter is for search the register.
Second parameter set new values.
For more information, you can read Eloquent: Getting Started - Documentation

Related

Difference between $object->attribute and $object['attribute'] in Laravel

I'm developing with DataTables in Laravel and trying to make an object manually using collect() to create a collection. When I push the collection into the DataTable, there is something wrong, and I can't call my object with this $object->attribute.
After I get the error with that, I already tried to call an attribute with $object['attribute'], and it works well.
Can someone give me insight about the differences and how I can convert $object['attribute'] into $object->attribute?
This is my query to create object
$result = collect();
$item = collect([
'row' => ($key+1),
'item_id' => $value->uid,
'item' => $value->nama_item,
'sub_kategori' => $value->sub_jenis_item->sub_jenis_item,
'kategori' => $value->jenis_item->jenis_item,
'gudang_id' => $id_gudang
]);
$result->push($item);
Accessing $object['attribute'] means $object is an array and accessing $object->attribute means $object is an object.
To convert array to object:
$object = (object) $object;
Additionally, to convert object to array:
$object = (array) $object;
DataTables calls internally toArray() on the collection items when you build the table. This happens during transformation of the data. It will also flatten nested objects (e.g. loaded Eloquent relations in case of an EloquentDataTable) into an array with depth 1 (per row of the table).
You can try the following way,
$result = collect();
$item = collect([
'row' => ($key+1),
'item_id' => $value->uid,
'item' => $value->nama_item,
'sub_kategori' => $value->sub_jenis_item->sub_jenis_item,
'kategori' => $value->jenis_item->jenis_item,
'gudang_id' => $id_gudang
]
);
$result->push($item);
$resultObj = json_decode($result);
foreach($resultObj as $obj){
echo $obj->row;
}

foreach function accessing multiple variables

I am using Laravel, and I have a foreach function like this
$name = person::find(1);
foreach($name as $dbitems) {
$person->services()->updateOrCreate([
'service' => $dbitems->Name,
'time' => $dbitems->Time
'price' => $anotherarrayhere
]);
}
In the place of $anotherarrayhere, I want to get this array from the outside of foreach function.
$anotherarrayhere = $peopleserviceprice[]
How can I include the $anotherarrayhere variable in the above foreach function?
foreach is not a function, you can use variables from outside the loop without problems. Maybe you're confused with collection callbacks that needs to specific tell variables
Any way, you're iterating over a model, not a collection, since you're using find.
$person = person::find(1);
$person->services()->updateOrCreate([
'service' => $person->name,
'time' => $person->time
'price' => $anotherarrayhere
]);

Laravel 5: How to saveMany() based on value

I need a little help with the following situation.
I am willing to saveMany based on the input value. Let me give code example.
I was experimenting with the following.
$data = [
'id' => 1,
'name' => 'example',
'number_of_slots' => 5,
'material' => 'Colo',
'equipment_status_code_id' => 1,
];
$platecontainer = PlateContainer::create($data);
foreach ($data as $key => $value) {
$platecontainer->containerSlots()->saveMany([
new ContainerSlot([
'plate_container_id' => $data['id'],
'slot' => $data['number_of_slots'],
'occuiped' => false,
])
]);
}
until $platecontainer everything works just great. What I want is when a PlateContainer is created using the data array, I want to create slots as well, but this one is based on number_of_slots
So for instance number_of_slots in the example is 5 so I want to save 5 records in (descending order) in the ContainerSlot table
so the containerslots table will end up looking something like this.
The save many method accepts an array of models, so just use a for loop for the $plateContainer's number_of_slots
$plateContainer = PlateContainer::create($data);
$containers = [];
// Need to add one to our number of slots because
// the $i count starts at one instead of zero.
$slots = $plateContainer->number_of_slots + 1;
for($i = 1; $i < $slots; $i++) {
$containers[] = new ContainerSlot([
'plate_container_id' => $plateContainer->getKey(),
'slot' => $i,
'occuiped' => false,
]);
}
$plateContainer->containerSlots()->saveMany($containers);
You can use createMany (array of arrays of attributes) instead of saveMany (array of models new or existing). Useful for API calls.
An alternative, if you want to insert data based on value, you can prepare your array and let the model insert in bulk.
$itemRebates = array_map(function ($rebateId) use ($payoutItem) {
return [
'rebate_id' => $rebateId,
'payout_item_id' => $payoutItem->id
];
}, $rebateIds);
PayoutItemRebate::insert($itemRebates);
This way you don't need to wrap your data in multiple model instances.
Additional details
I tried to use the insert method from $payoutItem->historyRebates() but it didn't take the payout_item_id from the relationship. So it's better to use the model itself.
My first attempt was to use saveMany, but even preparing the data, it doesn't work with arrays, only with model instances. I wanted to avoid that.

Optimization of an algorithm performed on a big array in PHP

I have a query that populates an array from the database. In some cases, this query returns a great amount of data, (let's say for purpose of an example, 100.000 records). Each row of the database has at least 6 or 7 columns.
$results = [
['id' => 1, 'name' => 'name', 'status' => true, 'date' => '10-01-2012'],
['id' => 2, 'name' => 'name 2', 'status' => false 'date' => '10-01-2013'],
...
]
I need to perform a substitution of some of the data inside the $results array, based on another one that give me some information about how i would change the values in the rows.
$model = [
'status' => ['function' => 'formatStatus', params => ['status']],
'date' => ['function' => 'formatDate', params => ['date']]
]
Now that i have all the data and what do i do with it i have the following routine.
foreach ($results as &$itemResult) {
$oldValues = $itemResult;
foreach ($itemResult as $attribute => &$value) {
if (isset($model[$attribute]['function'])) {
$function = $model[$attribute]['function'];
$params = $model[$attribute]['params'];
$paramsSize = count($params);
for ($i = 0; $i < $paramsSize; $i++) {
$newParams[] = $oldValues[$params[$i]];
}
$itemResult[$attribute] = call_user_func_array([$this, $function], $newParams);
$newParams = null;
}
}
}
So, for each attribute for each row of my data array, i run check for the existence of a function and params information. When the attribute in question needs to be replaced, i call the function via call_user_func_array and replace the value with the function return value.
Also notice that i am replacing the current array, not creating another, by passing the reference &$itemResult inside the loop, so in the end, i have the same array from the beginning but with all columns that needed to be replaced with its new values.
The thing is, for little arrays, this method is quite good. But for big ones, it becomes a pain.
Could you guys provide me some alternative to the problem?
Should i use another data structure instead of the PHP array?

How to make associative array in Yii2?

I would like to make associative array using foreach to use in Yii 2 dropdownlist.
My goal is to make array like following using foreach-
$array= [
['id' => '123', 'name' => 'abc'],
['id' => '124', 'name' => 'def'],
];
And then I want to use them using Yii 2 ArrayHelper::map().
$result = ArrayHelper::map($array, 'id', 'name');
How do I make the array using foreach?
Yii way to build items for drop-down list is exactly as you described, using ArrayHelper::map():
$items = ArrayHelper::map($array, 'id', 'name');
You don't need to use foreach here, just pass results of ActiveQuery as array:
$array = YourModel::find()->all();
Update:
Thanks. But here, I am actually calculating custom value for 'name'
and for that reason I want to use foreach to generate the array after
the calculation
You definetely need to add this information to the question, but anyway, you can use the ArrayHelper for that too. Take a look at toArray method. It can be used for both object / array of objects. After processing with this method you can use map.
Official docs:
ArrayHelper::map()
ArrayHelper::toArray()

Categories