updateOrCreate isn't filling all the fields in Laravel 5.6 - laravel

I have a code:-
$tokenUpdated = AppToken::updateOrCreate(
array(
'user_id' => $user_id, 'token' => $token),
array('expiry'=>$expiryTime,
'created_date'=>$created_at,
'modified_date'=>$created_at)
);
Though new rows are being inserted, the expiry, created_date fields values aren't getting saved. They records show NULL value which are default values.
What am I doing wrong?

First you need to check if expiry and created_date are returning values, if so then you could use the updateOrCreate function like this:
$tokenUpdated = AppToken::updateOrCreate(
['user_id' => $user_id, 'token' => $token]
['expiry'=>$expiryTime,
'created_date'=>$created_at,
'modified_date'=>$created_at
]
);
check laravel eloquent documentation: https://laravel.com/docs/5.6/eloquent

Related

Laravel firstOrNew based on created_at same date

I am using lumen. I want to use firstOrNew based on created_at. For example in my table there exists data for created_at = 2021-09-23 14:42:13 . For that cases it will update if request date value become that day. Here I tried with
$tableObj = User::firstOrNew([
'created_at' => Carbon::today() // date('Y-m-d')
]);
$tableObj ->mobile= '5457874545';
$tableObj ->save();
Here it always inserted new row. Thanks in advance
Can You Please Format the date
try
$tableObj = User::firstOrNew([
'created_at' => Carbon::today()->format('Y-m-d') // date('Y-m-d')
]);
$tableObj ->mobile= '5457874545';
$tableObj ->save();
or use UpdateOrCreate method of laravel
$tableObj = User::updateOrCreate(
['created_at' => Carbon::today()->format('Y-m-d')],
['mobile'=>'5457874545']
);

How to use Rule:unique with array of values compared to another column in laravel?

i have a request for array of values and i validate it with the following code
$request->validate([
'doctor_id.*' => ['required'],
'doctor_id' => [Rule::unique('project_orders')->where(function ($query) use ($student) {
$query->where('student_id', $student->id);
})],
]);
but the unique validation doesn't work and the data was inserted to the table with duplication
i want the doctor_id field to be unique with the student_id column, what should be the correct rule?
any help please ?
First you need to do validation on database level, so you will add in your migration
$table->unique(['doctor_id', 'student_id']);
This will make sure that there will be no duplication for same doctor_id and student_id values
Then in your validation layer you will add
$request->validate([
'doctor_id.*' => 'unique:project_orders,doctor_id,NULL,id,student_id,'.$student->id,
]);
You can do the validation like this
$request->validate([
'doctor_id.*' => [ Rule::unique('project_orders', 'doctor_id')->where('student_id', $student->id) ]
]);

Laravel updateOrCreate Timestamp Updating Issue

I am using the updateOrCreate method to check whether data has been changed from a response which is entered in the DB. If the record is new then it successfully adds the correct timestamp. However, I have noticed that the updated timestamp updates record for all of the records. I want this to only update if records have been updated.
But looking at the issue I believe all the records are being updated regardless.
if (isset($customers->Data)) {
foreach ($customers as $customerData) {
if ($customer = $customerData->attributes()) {
if ((string) $customer->CustomerType !== 'A') continue;
if ((string) $customer->CustomerEmail === '') continue;
$customerDb = $this::updateOrCreate(
[
'email' => $customer->CustomerEmail,
'code' => $customer->Customer,
'currency' => $customer->Currency,
],
[
'email' => $customer->CustomerEmail,
'code' => $customer->Customer,
'currency' => $customer->Currency,
'name' => $customer->CustomerName,
'phone' => $customer->CustomerPhone,
'terms' => $customer->Terms,
]
);
}
}
}
The email, code, currency fields will always be unique and the rest to create if these are not present. Should the default behavior be that it updates regardless? What I want to achieve is to only detect if a record has been changed if it has then updated that particular field and update the timestamp if it's not there then create it. Thus filtering out what has been updated and only show these records rather than the whole table.
Sorry but new to Laravel any guidance is welcome thank you.

Automatically use Timestamp in Laravel 5.4 Query builder

is there any way to automatically use time-stamp when using query builder, currently I'm using CARBON.
here is my code:
DB::table('product_in_out')->insert(
['product_id' => $product_id,
'warehouse_id' => $warehouse_id,
'balance_before' => Product::getProductBalanceOf($action_id, $product_id),
'in' => $product_qty,
'out' => '0',
'after_balance' => Product::getProductBalanceOf($action_id, $product_id)+$product_qty,
'action' => 'ProcurementReceipt',
'action_id' => $action_id,
'created_by' => auth()->user()->id,
'updated_by' => auth()->user()->id,
'is_active' => '1',
'created_at' => \Carbon\Carbon::now(), # \Datetime()
'updated_at' => \Carbon\Carbon::now(),# \Datetime() ]
);
Fields created_at and update_at are part of Eloquent.
You need to use Eloquent instead of query builder to insert and update the record in to database for automatic time handling. Eloquent will handle auto update of updated_at column for you,
here is the way,
If you have model name Product,
$product = new Product();
$product->column_name = $column_value;
....
...
$product->save();
Above code will add time stamp automatically at created_at and updated_at column.
Now use Eloquent to update your records like,
$product = Product::find($id);
$product->update_column_name = $update_value;
...
...
$product->update();
This will update your updated_at column value accordingly.
Hope you understand.
Use Laravel Macros:
https://medium.com/fattihkoca/laravel-auto-save-timestamps-with-query-builder-without-using-eloquent-123f7ebfeb92
It is wise to create a macro to avoid typing the same things every time.
insertTs method inserting records into database with created_at data:
DB::table('users')->insertTs([
'email' => 'john#example.com'
]);
$id = DB::table('users')->insertGetIdTs([
'email' => 'john#example.com'
]);
updateTs method updating records into database with updated_at data:
DB::table('users')
->where('id', 1)
->updateTs(['email' => 'john#example.com']);
deleteTs method deleting records into database with deleted_at data (soft delete):
DB::table('users')
->where('id', 1)
->deleteTs();

Eloquent update and limit

I could not figure out how can i use both update and limit methods in laravel eloquent orm.
$affectedRows = Promo::where('used','=',0)
->update(array('user_id' => Auth::user()->id))
->limit(1); // Call to a member function limit() on a non-object
//->take(1); // Call to a member function take() on a non-object
I tried both limit and take methods.
I want to do only one result will be update.
But i think, i can not use limit or take methods on update.
Is there any way to update only one row via eloquent?
Add :
Eloquent ORM
$affectedRows = Promo::where('user_id','=',DB::raw('null'))->take(1)
->update(
array(
'user_id' => Auth::user()->id,
'created_ip' =>Request::getClientIp(),
'created_at' => new DateTime,
'updated_at' => new DateTime
)
);
Query Builder
$affectedRows = DB::table('promos')->whereNull('user_id')
->take(1)
->update(array(
'user_id' => Auth::user()->id,
'created_ip' =>Request::getClientIp(),
'created_at' => new DateTime,
'updated_at' => new DateTime
));
These two codes did not add limit param to the query
Output:
update `promos` set `user_id` = '1', `created_ip` = '127.0.0.1', `created_at` = '2013-06-04 14:09:53', `updated_at` = '2013-06-04 14:09:53' where `user_id` = null
Talking about laravel 5 (not sure about L4), depends on db engine.
MySQL supports limit for update so it works, here is the laravel code that do that:
https://github.com/laravel/framework/blob/5.4/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php#L129
so, first ->limit(1) and then ->update([fields]);
DB::table('table')
->where('field', 'value')
->limit(1)
->update(['field', 'new value']);
I used raw query. There is no method limit/take for update and delete queries on both eloquent and query builder. Use
DB::update(DB::raw("UPDATE query"));
like this.
I have not tried it but the Laravel 4 logic makes me think this syntax would work :
$affectedRows = Promo::where('used','=',0)
->limit(1)
->update(array('user_id' => Auth::user()->id));

Resources