Trying to create a GROUP BY with eloquent - laravel

$collections = Collection::selectRaw("DATE(created_at) as collection_date, sum(gross_amount) as amount")
->groupBy('collection_date')
->paginate(10);
When I do that it displays that collection_date does not exist in the table, so I wonder how can I create a group by with just DATE() in eloquent?
Thanks

Based on Laravel docs, pagination doesn't work with the groupBy clause properly.
https://laravel.com/docs/7.x/pagination#paginating-query-builder-results
Currently, pagination operations that use a groupBy statement cannot be executed efficiently by Laravel. If you need to use a groupBy with a paginated result set, it is recommended that you query the database and create a paginator manually.

Related

Query database table using LIKE in Laravel

I am trying to query a table using where like :
Auth::user()
->friends
->where('friend.first_name','LIKE','%'.$firstName.'%')
->all()
The query does work properly without using the LIKE statement only when i add the LIKE keyword it doesn't return any results.
Using all() will work without the builder where() statement.
When grabbing data using the query, use get() instead:
Auth::user()->friends->where('something','LIKE','%'.$something.'%')->get()
I think you are confused between a laravel relation and a eloquent collection. First let me go straight to answer, you would have to do
Auth::user()
->friends()
->where('friend.first_name','LIKE','%'.$firstName.'%')
->get()
To explain what's wrong with your code, ->where('name', 'Like', '%something%') This is a query builder method. You have to use it on the query builder, or Before you actually retrieve the model / model collection.
Auth::user()->friends()
This would give you a relation Illuminate\Database\Eloquent\Relations\HasMany that you can apply where like on.
Auth::user()->friends
This will return you a Illuminate\Database\Eloquent\Collection. And yes, it is a collection, so you will have to use collection method. Take a look at the where method for collection. You can see it only support key => value pair. It does not support "LIKE"
The where method filters the collection by a given key / value pair:
If you want to use achieve a "Like" on collection, you can probably use the filter method, which support custom callback.
The filter method filters the collection using the given callback, keeping only those items that pass a given truth test:
To conclude, when you define a friends "HasMany" relation on User, you have two way to retrieve it.
If you want to apply additional query builder method, you need to use user->friends() which do not return you data, it return you a relation that you can use query builder method. Once you do user->friends, it get you a collection. You cannot apply query builder on that anymore. So basically, user->friends is act the same way as user->friends()->get()
Don't Use all() and use get().
Auth::user()->friends()->where('something','LIKE','%'.$something.'%')->get()

Create pagination from groupBy in laravel 5.8

$payments = Payment::with('borrowerUser','collectorUser')
->get()
->groupBy('date_paid');
which gives me this result
My question is, is it possible for me to put a pagination in this scenario?
I already tried
$payments = Payment::listings()
->with('borrowerUser','collectorUser')
->groupBy('date_paid')->paginate(5);
and put {{$payments->listings()}} on my blade
but that doesn't work.
any suggestions? thank you in advance!
put this code in controller:
$payments = Payment::with('borrowerUser','collectorUser')
->groupBy('date_paid')->paginate(5);
put below code in blade file after for loop is completed
{!! $payments ->render() !!}
This is the must read content from the laravel documentation
Currently, pagination operations that use a groupBy statement cannot
be executed efficiently by Laravel. If you need to use a groupBy with
a paginated result set, it is recommended that you query the database
and create a paginator manually.
Documentation link
You can use orderBy clause after groupBy to get the result, but still it won't give you efficient results

Laravel/Eloquent pagination and groupBy for a postgres materialized view model

I've created a materialized view: accounts_index that has a couple left joins, so I need to do a group by with the eloquent model. I also need to paginate the collection and am having trouble nailing the order of things. The materialized view:
CREATE materialized VIEW accounts_index
AS SELECT a.account_uuid,
a.account_no,
a.person_owner_uuid,
a.company_owner_uuid,
a.account_group_uuid,
a.account_scope_uuid,
a.created_at,
a.deleted_at,
s.service_uuid,
s.status,
st.service_type
FROM accounts a
LEFT JOIN services s
ON a.account_uuid = s.account_uuid
LEFT JOIN service_types st
ON s.service_type_uuid = st.service_type_uuid
The eloquent model can grab that table like so: AccountIndex::all();.
I could paginate that: AccountIndex::paginate(); or do a groupBy: AccountIndex::all()->groupBy('account_uuid');, but lost on how to combine the two. Some attempts:
AccountIndex::all()->groupBy('account_uuid')->paginate(): Method Illuminate\Database\Eloquent\Collection::paginate does not exist.
AccountIndex::paginate()->groupBy('account_uuid');: returns the collection without paginating.
$accountsIndex = collect(\DB::table('accounts_index')->get());
$accountsIndex->groupBy('account_uuid')->paginate();: Same Method Illuminate\Support\Collection::paginate does not exist. exception.
The main problem I'm trying to solve is that these joins will be returning accounts that have multiple services (so multiple rows) and I need to then group by the account_uuid. Thanks in advance for any insights!
paginate method is related to Illuminate\Database\Query\Builder or Illuminate\Database\Eloquent\Builder classes, it is not exists in Collection class,
the corresponding method for it in Collection class is forPage method, you can get more information from the documentation
almost
AccountIndex::groupBy('account_uuid')->paginate()
paginate actually DOES something
groupBy() is just writing SQL just like ->where() ->join() etc that all prepares an SQL statement you can try by running ->toSql() returns an sql string.
get() all() paginate() all actually do something e.g. execute the SQL.

Data processing using eloquent orm methods

I am very beginner to PHP and Laravel.
I am using laravel 5 eloquent ORM. I have an array $caseIDs and want to fetch the data from db where caseID (column name) matches from one of the $caseIDs elements. Can I use where() method of eloquent ORM? or How can i do it?
You need to use whereIn which simulates a WHERE IN('comma','separated','values')
YourModel::whereIn('caseID', $caseIDs)

Laravel not returning join query to blade

I have two queries, one is lighter on data by using the pivot table as a filter to get data from the main table (student in this case).
$students=\DB::table('student')->join('school_student', 'student.id', '=','school_student.student_id')->get();
This returns a query result from the controller. But will not load into the blade:
$this->layout->content=\View::make('admin.students.index')->with('student', $students);
Whereas this versions returns a similar more data heavy (i.e. outputs all school data each time)
but works in blade.
$students = \Student::with(array('schools' => function($query){$query->where('school_id', '=', 1);}))->get();
Is it simply that DB and view are incompatible?
If so what is the Laravel 4 method to query one table and it's pivot only.
Any help appreciated.
In the blade
#if($student->count())
The first example produces this error:
Call to a member function count() on a non-object
DB::...->get() returns an array, so you can't call ->count() on it (hence "non-object"), but instead you need count($students).
The reason ->count() works when you do the 'more data heavy' method is that you're using Eloquent and it returns Eloquent Collections.
So, basically, you're doing two different things and expecting to treat them the same.
Also, while I'm here I should point out that I think your Eloquent query isn't quite right. First off you're hardcoding the id as 1 (whereas in the DB-style query you don't care about the school ID, and you just use it to join to the pivot table - maybe you used an incomplete query), but also you're using with but you should probably look at has. with eager-loads models, but has is what you want if you just want to check for a condition on a join table.

Resources