Eloquent update and limit - laravel

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));

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']
);

updateOrCreate isn't filling all the fields in Laravel 5.6

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

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();

Laravel Update Multiple Columns with QueryBuilder

I'm using Query builder, I successfully update na first column but on the second query the change doesnt happen, I already checked the view part the name of input and its correct. here is my code.
DB::table('area')
->where('id', $request->get('area_id'))
->update(['island_group_id' => $request->get('island_group_id')],
['region_id' => $request->get('region_id')]);
return 'test';
$updateDetails = [
'island_group_id' => $request->get('island_group_id'),
'region_id' => $request->get('region_id')
];
DB::table('area')
->where('id', $request->get('area_id'))
->update($updateDetails);
DB::table('area')
->where('id', $request->get('area_id'))
->update([
'island_group_id' => $request->get('island_group_id'),
'region_id' => $request->get('region_id')
]);
return 'test';
I think it will be helpful to you.
$area_id = $request->get('area_id');
$island_group_id = $request->get('island_group_id');
$region_id = $request->get('region_id');
$update_details = array(
'island_group_id' => $island_group_id
'region_id' => $region_id
);
DB::table('area')
->where('id', $area_id)
->update($update_details);
Because you use every time new array for update field. Please use one array for update multiple field like:
DB::table('area')
->where('id', $request->get('area_id'))
->update(array(
'island_group_id'=>$request->get('island_group_id'),
'region_id'=>$request->get('region_id')
));

Laravel Eloquent ORM relationship query

I need help, I have a problem with querying Model Relationships.
I actually know and get the job done using the query method but I'd like to know the "laravel way" of querying relationships.
Here's what's on my controller.
//HealthProfile Controller
//$id value is 2
$health_profiles = User::find($id)->with('health_profiles')->first();
problem is that the return for the query is the records for id = 1 and not id = 2. It basically ignored the "find" method. I just want to get the health profiles for a specific user_id.
[id] => 1
[firstname] => patrick
[lastname] => marino
[email] => patrick#gmail.com
[membership_code] => starpatrick
[birthdate] => 1989-05-17
[contact_number] => 1230123
[active] => 1
[created_at] => 2014-07-01 16:10:05
[updated_at] => 2014-07-01 16:10:05
[remember_token] =>
[health_profiles] => Array
(
[0] => Array
(
[id] => 1
[user_id] => 1
[parent_id] =>
[name] => patrick star
[relationship] =>
[gender] => male
[birthdate] => 1989-05-17
[marital_status] =>
[number_of_children] =>
[weigth] =>
[height] =>
[blood_type] =>
[blood_pressure] =>
[hdl] =>
[ldl] =>
[vldl] =>
[visual_activity] =>
[lifestyle] =>
[current_bmi] =>
[weight_goal] =>
[weekly_goal] =>
[rdc] =>
[created_at] => 2014-07-01 16:10:05
[updated_at] => 2014-07-01 16:10:05
)
This is my schema
//User model
public function health_profiles()
{
return $this->hasMany('HealthProfile');
}
//HealthProfile model
public function user()
{
return $this->belongsTo('User', 'user_id', 'id');
}
First a few words of explanation:
find($id) already runs the query (it uses where(id, $id)->first() under the hood) so place it at the end, because now you unwittingly did this:
User::find($id);
User::with('health_profiles')->first();
Another problem is, like you already noticed, that Eloquent won't work with this setup:
public function health_profiles() ...
$user = User::find($id);
$user->health_profiles; // null
because when loading dynamic properties (relations) it looks for camelCased method on the model.
However eager loading will work as expected:
$user = User::with('health_profiles')->find($id);
$user->health_profiles; // related model/collection
So you definitely should comply with the naming conventions if you want Eloquent to be your friend ;)
But that's not all. It will work the other way around:
public function healthProfiles() ...
$user = User::find($id);
$user->healthProfiles; // works, returns related model/collection
$user->health_profiles; // works as well, returns the model/collection
To sum up and answer your question, each of those will work for you:
// Assuming Profile is the model
// 2 queries
$user = User::find($id);
$profiles = $user->healthProfiles;
// or 1 query
$profiles = Profile::where('user_id', $id)->get();
// or 2 queries: 1 + 1 subquery
$profiles = Profile::whereHas('user', function ($q) use ($id) {
$q->where('users.id', $id);
})->get();
You can try putting the with before the find so that the builder knows to eager load that relationship on what you are trying to find.
$user = User::with('health_profiles')->find($user_id);
$health_profiles = $user->health_profiles;
Try this
User::with('health_profiles')->find($id);
I don't think you need to call the first method because find as it's stated will only find the one row of data that you need.
I've found the culprit. L4 has problems with snake cased methods! I changed it to camelCase and it worked.
$lawly = User::where('id', '=', 2)->first();
$lawly->healthProfiles->toArray()
src: https://coderwall.com/p/xjomzg

Resources