Reputation: 89
I have an array that is multidimensional or nested, I'm not sure about the correct word. The thing is that I'm trying to look for a specific key, return its value and store it in my database in one iteration. This is what I've been trying but is creating me a lot of rows in my database when I just need 1.
$arr = $json['confirmed_by_province'];
foreach ($arr as $province) {
$confirmedByStates = new ConfirmedByProvinces();
foreach ($province as $key => $value) {
if($key == 'ON') {
$confirmedByProvinces->ontario = $value;
}
if($key == 'QB') {
$confirmedByProvinces->quebec = $value;
}
$confirmedByProvinces->save();
}
};
Here is the data on the $arr variable:
array:31 [
0 => array:1 [
"ON" => "60"
]
1 => array:1 [
"QB" => "46"
]
Upvotes: 1
Views: 104
Reputation: 7111
Avoid as much as in your power DB actions in foreach loop. In case here, you can set all from loop into array and save it into DB in one query instead:
$insert = [];
foreach ($arr as $k => $province) {
foreach ($province as $key => $value) {
if ($key == 'ON') {
$insert[$k]['ontario'] = $value;
}
if ($key == 'QB') {
$insert[$k]['quebec'] = $value;
}
}
// add timestamps here if needed since insert() method doesn't make that automatically
// $insert[$k]['created_at'] = \Carbon\Carbon::now();
// $insert[$k]['updated_at'] = \Carbon\Carbon::now();
}
if (!empty($insert)) {
$confirmedByStates = new ConfirmedByProvinces();
$confirmedByStates->insert($insert); // one I/O with DB
}
Upvotes: 0
Reputation: 16339
The issue stems from your loop, if we actually stop and look at what is happening, it will make a lot more sense:
foreach ($arr as $province) {
$confirmedByStates = new ConfirmedByProvinces();
foreach ($province as $key => $value) {
if($key == 'ON') {
$confirmedByProvinces->ontario = $value;
}
if($key == 'QB') {
$confirmedByProvinces->quebec = $value;
}
$confirmedByProvinces->save();
}
};
For each iteration you are newing up a new model called ConfirmedByProvinces
:
foreach ($arr as $province) {
$confirmedByStates = new ConfirmedByProvinces();
//...
At the end of each iteration, you are then calling save()
:
foreach ($arr as $province) {
//...
$confirmedByProvinces->save();
As you can now see, each iteration of the outer loop will new up an instance of your ConfirmedByProvinces
model and then save it on the inner loop, resulting in multiple rows for as many entries there are in your array.
@DilipHirapara's answer will solve your issue, but I figured a more in depth explanation would make it clear why it was a problem to begin with.
Upvotes: 2
Reputation: 15296
use $confirmedByProvinces->save();
method out side of $province
array.
foreach ($arr as $province) {
$confirmedByStates = new ConfirmedByProvinces();
foreach ($province as $key => $value) {
if($key == 'ON') {
$confirmedByProvinces->ontario = $value;
}
if($key == 'QB') {
$confirmedByProvinces->quebec = $value;
}
}
$confirmedByProvinces->save();
};
Upvotes: 2