I am trying to use Laravel updateOrCreate
to update a record if its within this month and last month based on if an ID exists.
\App\Models\Result::updateOrCreate(
[
'id' => $request->get('id'),
// where created_at is within the last 2 months
'created_at' => [
'>',
\Carbon\Carbon::now()->startOfMonth()->subMonthsNoOverflow()
],
],
[
'discipline_one' => $request->get('d-one'),
'discipline_two' => $request->get('d-two'),
'discipline_three' => $request->get('d-three'),
'discipline_four' => $request->get('d-four'),
'discipline_five' => $request->get('d-five'),
'discipline_six' => $request->get('d-six'),
]
);
If the ID exists, and the result is in this current month or last, a new record is created instead of updated.
Expected input: 1 (which exists from last month)
Expected output: Record is updated
Expected input: 2 (which doesn't exist or is not within 2 months)
Expected output: New record is created
Update:
Using the answer suggested,
'id' => $request->get('id'),
'created_at' => \App\Models\Result::whereBetween('created_at', [
\Carbon\Carbon::now()->startOfMonth()->subMonthsNoOverflow(),
\Carbon\Carbon::now()->endOfMonth(),
]),
I get the error:
Object of class Illuminate\Database\Eloquent\Builder could not be converted to string
CodePudding user response:
Here you go:
You only need to explicitly define the operators in the method's first parameter.
Each element of the array in the method's first parameter should be an array containing the three arguments.
column, operator, value
$startDate = \Carbon\Carbon::now()->startOfMonth()->subMonths(2);
$endDate = \Carbon\Carbon::now()->endOfMonth();
$resultRow = \App\Models\Result::query()
->where('id', $request->id)
->whereBetween('created_at', [$startDate, $endDate])
->first();
\App\Models\Result::updateOrCreate(
[
[
'id', '=', $request->get('id'),
],
[
'created_at', '>=', $startDate,
],
[
'created_at', '<=', $endDate,
],
],
array_merge(
[
'discipline_one' => $request->get('d-one'),
'discipline_two' => $request->get('d-two'),
'discipline_three' => $request->get('d-three'),
'discipline_four' => $request->get('d-four'),
'discipline_five' => $request->get('d-five'),
'discipline_six' => $request->get('d-six'),
],
$resultRow ? [] : [
'id' => $request->get('id'),
'created_at' => \Carbon\Carbon::now()
]
)
);
Notice that I repeated id
& created_at
column settings in the method's second parameter. It's because contrary to the regular behaviour, a merge of the 2 method's parameter arrays wasn't performed based on my tests if no result was found with that criteria.