Laravel Update only 1 row? - laravel-5

Is there a way to update only 1 row in Laravel 5? I want to set the value of selected to true from only 1 row, ordered by id:
Ill tried:
DB::table('user_tabs')->where('user_id', '=', $user_id)->orderBy('id', 'desc')->take(1)->update(array('selected' => true));
And:
DB::table('user_tabs')->where('user_id', '=', $user_id)->orderBy('id', 'desc')->first()->update(array('selected' => true));
but it is not working. Any ideas?

Try this:
DB::table('user_tabs')->where('user_id', $user_id)->update(['selected' => true]);
You were trying to update the record after selecting it, which confused the Query Builder.
Also, have a look at Eloquent models. They make database interactions a little nicer.

Related

I want to extract the first five data that match the where clause from Laravel relationships

I'd like to do something like this with Laravel's Eloquent:relationship, but it doesn't work.
$playlist->setRelation('tags', $playlist->tags->where('privacySetting', 'public')->take(5));
It works without where clause, but I want to retrieve the first 5 data in the tags relationship table that match the where clause.
How can I do this?
Laravel version is 7.28.1.
this will select top 5 based on criteria from model
$playlist = Playlist::with(['tags' => function($filter){
return $filter->where('privacySetting', 'public')
->take(5);
}])
->get();
//try dd($playlist);

Update model which having multiple rows

I have an object model which have multiple rows like result getting with this query:
$cities = City::whereIn('id' , [1,2,3])->get();
What I want to do is update each row with the same value without using each because each is making a query on each row, so in above query I will have 3 queries.
Instead of doing this:
$cities->each->update(['name' => 'test']);
I want to do something like this as I already have the model object, but it doesn't work:
$cities->update(['name' => 'test']);
Instead I must do something like this to make it work:
City::whereIn('id' , $cities->pluck('id'))->update(['Avatar' => 'test']);
My question is; Why can't I use this:
$cities->update(['name' => 'test']);
When you use ->get() method you are getting not a model, but an collection of models.
There is no such thing as multiple row models. Models has only one "row".
There is an example for that in the documentation:
App\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]);
See the mass update section.
So, in your case the query must be:
City::whereIn('id' , [1,2,3])
->update(['name' => 'test']);

Laravel Eloquent increment without updating timestamps

I have an Eloquent model on which I would like to increment a single attribute. So far I've been using the following line of code to achieve this:
Thread::where('id', $threadId)->increment('like_count');
This however has the unwanted side-effect of updating the updated_at timestamp. I've found the following way of updating a record without altering the timestamp:
$thread = Thread::where('id', $threadId)->first();
$thread->timestamps = false;
$thread->like_count++;
$thread->save();
But that suddenly looks a lot less concise. Therefore, I would like to know of there's a way to use the increment method without updating timestamps.
If you do not need timestamps at all, you can disable it once for all for that particular model using :
public $timestamps = false; inside your model. This will add additional step that whenever you want the timestamps to be updated, you need to assign them value manually like $object->created_at = Carbon::now()
Secondly, if you want those disabled for particular query, then as you mentioned in your question is one way.
Another way is using query builder. Now timestamps is the functionality associated with Eloquent. However, if you update using simple query builder, it does not update timestamps on its own.
So you can do :
DB::table('threads')
->where('id', $threadId)
->update([ 'votes' => DB::raw('votes + 1') ]);
However, I will personally prefer using Eloquent way of doing this if given a choice.
Update
You can now pass additional parameter to increment function to specify what other columns you would like to update.
So this will become :
$thread = Thread::find($threadId);
$thread->increment('votes', 1, [
'updated_at' => $thread->updated_at
]);
old thread but with laravel 7 and php7.4 you can do
Thread::where('id', $threadId)
->where(fn($q) => $q->getModel()->timestamps = false)
->increment('like_count');
older versions of php:
Thread::where('id', $threadId)
->where(function($q) {$q->getModel()->timestamps = false;})
->increment('like_count');
You could encapsulate the whole process into one method of the model.

Order an Eloquent model by relationship count and then pluck out that count

I got this far:
return \App\Project::with('likes')->get()->sortByDesc(function($project) {
return $project->likes->count();
})->lists(['title', 'likes']);
And the desired result is:
array('Some title' => 43, 'Some other title' => 11)
Is this even achievable with Eloquent? Or should I just build up an array 'manually'?
Edit
Basically, I want to achieve the following:
\DB::table('projects')
->join('likes', 'projects.id', '=', 'likes.project_id')
->select(\DB::raw('title, count(likes.id) as likes'))
->groupBy('projects.id')
->get();
but Eloquent way..
I also tried setting getLikesCountAttribute method, and now I can do:
\App\Project::all()->sortByDesc('likesCount')->lists('likesCount', 'title');
which works fine, but as you can see - this way I have to retrieve all the records first, and then get that count using the magic getLikesCountAttribute method. Perhaps not that big of a deal, don't know..

Laravel4.2 ORM Eloquent Update Method

I want to know the problem related to this code, first I use a table without primary key when I run the following code to an update, I did not have any answer:
Upload::where('nameimgs', '=', $imgsended)
->update(array('nameimgs' => $ imgname));
but the problem is solved when I replace the code by :
DB::table('uploads')
->where('nameimgs', '=', $ imgsended)
->update(array('nameimgs' => $ imgname));
nevertheless with the deleting method, i did not have any problem, to share knowledge with laravalists I want to know if the problem is related to version Laravel4.2 or Laravel ORM eloquent for the update method require the primary key "id" as like as the save method.
Is the exact code you have in your project? If so, you have spaces in the field names, and you are missing a comma in the first where.
Upload :: where ('nameimgs '' = ', $ imgsended) -> update (array (' nameimgs' => $ imgname));
DB :: table ('uploads') -> where ('nameimgs', '=', $ imgsended) -> update (array ('nameimgs' => $ imgname) );
It should look like this:
Upload::where('nameimgs', $imgsended)
->update([
'nameimgs' => $imgname
]);
DB::table('uploads')
->where('nameimgs', $imgsended)
->update([
'nameimgs' => $imgname
]);
Try my code see if that fixes anything. If that doesnt work, can we see you Upload model?

Resources