Laravel Query builder: Take and limit methods - php

I dont undertand how these methods work, I'm trying to get last records inserted in my db and for this, I need a query builder so I made y consult with something like this:
$costo = Costo_promedio::where('producto_nombre_id',$id_prod->id)->latest()->take(1);
The thing is I'm still getting all records inserted, in these methods take or limit I send the paramether of how many i want to get, and my question is. Why does this happen??
And no, I dont want to use the first() or get() methods these dont work when you do server side processing in a datattable

first() is not return Collection. It returns a Model instance. Maybe you are not clear about Collection vs Model instance.
$costo = Costo_promedio::where('producto_nombre_id',$id_prod->id)->latest()->first();
Alternative:
$costo = Costo_promedio::where('producto_nombre_id',$id_prod->id)->latest()->get();
// $costo[0]

take(1) or limit(1) just adds limit 1 to the query in builder. You need to call get() to fetch the results and it will return a Collection and you can get its only element by calling first() on it.
$costo = Costo_promedio::where('producto_nombre_id',$id_prod->id)->latest()->take(1)->get()->first();
Or you can replace take(1)->get()->first() with just first()
$costo = Costo_promedio::where('producto_nombre_id',$id_prod->id)->latest()->first()
first() will add limit 1 and fetch the results and return the only item that's there

Try this
$costo = Costo_promedio::orderBy('created_at','desc')->take(3)->get();
That Will get the last three records from the database assuming that your timestamp is named created_at.

Related

Why is it not possible to use groupBy() in an eager loading query - Laravel

ErrorException:
stripos() expects parameter 1 to be string, object given
For the groupBy() call in the with() method
$user = User::with([
'pricelists' => function($query) {
$query->groupBy(function($var) {
return Carbon::parse($var->pivot->created_at)->format('m');
});
}
])->where('id', $id)->get();
I already saw a few posts talking about how to manage this problem and that it shall not be possible to use groupBy() in eloquent but I do not really understand why...
To be clear:
User and Pricelist model got a many-to-many relationship with the default timestamps() method. I am trying to get the downloaded pricelists grouped by their months they were downloaded from the current user.
After a few attempts I just deleted the above shown => function($query... statement from the with() method and just left the with(['pricelist']) to fetch all datasets and tried this:
$user->pricelists = $user->pricelists->groupBy(function($var) {
return Carbon::parse($var->pivot->created_at)->format('m');
});
return $user->pricelists;
And it works fine and returns an array with multiple arrays for each month... But returning it like this:
return $user;
returns just 1 array with all entries... I do not really get the sense behind it right now...
The two groupBy() method that you are using in the two code you provide are totally different methods.
The first groupBy() where you use it in the callback is actually being called by $query which is a query builder object. The groupBy() here is used to add SQL GROUP BY Statement into the query. And as per the documentation, it only take string variables as parameter.
The groupBy() in your second code is being called by $user->pricelists which is a laravel eloquent collection. The groupBy() method here is actually from the base collection class and is used to group the items inside the collection into multiple collections under the different key defined by the parameter passed to the function. Please read the documentation here.
For your case, the second groupBy() is the one you should be using since you plan to use a callback and will allow you to use more complicated logic.

Catch and save elements in Laravel, not by primaryKey

I need to get an element from the database, but I can not get it by the FIND method, since FIND only finds it by the primaryKey and what I need is not by my primaryKey. So I did like this:
$user = Pac::find($request->pac_id);
$element = query()->where('med_cart', $user->pac_id)->get();
$element->med_obs = $request->med_obs;
$element->save(); // error
Now I need to save this element, however, I can not use the SAVE method, as I believe it is fully connected with FIND and FINDORFAIL (if anyone knows, explain to me which methods I can use the SAVE method).
How can I save them the way I did? Or is there some other way to do it?
Because I need to get the element with a data other than the primaryKey and then save it, then I can not use FIND or FINDORFAIL, I think.
The function ->find() returns an Eloquent Model instance and you can then call ->save() on the model instance.
You're using ->get() which returns a Collection.
To update your query (that may target one or more entries) just perform the update statement directly from the QueryBuilder by replacing ->get() with ->update(['med_obs' => $request->med_obs]).
Be aware that when doing this you are now using Fluent queries, instead of eloquent. This means that any logic you may have defined in the boot function of your model is not evaluated.
If you are certain that you only have a single result you can append ->first() to your query, which will return a Model of the first result that matches your ->where clause. You can then call ->save() on it:
$user = Pac::find($request->pac_id);
$element = query()->where('med_cart', $user->pac_id)->first();
$element->med_obs = $request->med_obs;
$element->save();

Laravel recovering the id of the return of a json

I'm having a problem retrieving data from a select.
When I perform the following select
$Projeto = $this->ModelProjeto
->select('projeto.*','tipoprojeto.descricao')
->join('tipoprojeto','tipoprojeto.id','=','projeto.tipoprojeto')->get();
and returns json
[{"id":1,"descricao":"house","tipoprojeto":1,"tipoprojetodescricao":"Engenharia Civil"}]
When I try to retrieve the json id with the following command: return $Projeto->id; error appears
Property [id] does not exist on this collection instance.
if I used the find method, it would work normally, but it is not possible to use join, so how do I access Project-> id using the -> get () method?
The get() method returns a collection, not an individual item.
$Projetos = $this->ModelProjeto
->select('projeto.*','tipoprojeto.descricao')
->join('tipoprojeto','tipoprojeto.id','=','projeto.tipoprojeto')
->get();
// you would need to loop the $Projetos to get each id
$Projetos->each->id
// or use the first() method if you know only one item is returned
$Projeto = $this->ModelProjeto
->select('projeto.*','tipoprojeto.descricao')
->join('tipoprojeto','tipoprojeto.id','=','projeto.tipoprojeto')
->first();
Looking at the JSON, this is an array, so instead of using get(), use first()
$Projeto = $this->ModelProjeto
->select('projeto.*','tipoprojeto.descricao')
->join('tipoprojeto','tipoprojeto.id','=','projeto.tipoprojeto')->first();
This will make sure only 1 record is returned and that it will return an object instead of a collection

what is difference between where and find in laravel

when I write this $thread = Thread::find($id); then I write {{$thread->title}} it gives me the title of the thread, but when I write $thread = Thread::where('id','=',$id); then I write {{$thread->title}} it gives me an error.why is that happening?
You should write:
$thread = Thread::where('id','=',$id)->first();
to get one column, else laravel will understand it as array.
You need to call the get() (or any of its variants) method to execute the actual query when using where.
Thread::where('id','=',$id)->get();
Otherwise Thread::where('id','=',$id) just gets you an instance of eloquent's query builder.
find() on the other hand will automatically run a query for whatever it is you want to find by you can't do all sorts of useful stuff (e.g. orderBy, paginate, etc.) that you can very easily pull of using the query builder.

Eloquent ORM returning collection with single item

Using Laravel 4.2 and eloquent ORM, I know that all multi-result sets returned by a query will return a Collection object, as documented here (http://laravel.com/docs/eloquent#collections).
I am running a query that returns a single object:
$faq = ProductFaq::where($where)->with('products')->get();
However, I'm being returned a collection.
In order to use the result do I need to chain ->first() to the end of my statement? I'm just confused if the docs are saying that every call that uses get() will return a collection, or only get() calls that have multiple results.
Get returns a Collection instance, you should call first instead of the get method
$faq = ProductFaq::where($where)->with('products')->first();

Categories