Laravel: Use "where" in View? - laravel

Is it possible to use where in a view where I passed a collection toß
For example: I have a collection i pass to my view as $statuses.
Inside the view I want to filter the collection for statistic purposes:
Is it possible to do something like this?
{{ $statuses->where('category', '=', 'open')->count() }}

Yes, it's possible, because there are where() and count() methods for collections too.
You can see all available methods for collections here

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

Retrieving a single value from belongsToMany relationship in blade template

I have created a model with a belongsToMany relationship. The model is Vendor and the relationship with Location. So, in my blade template, I would normally do something like this:
#foreach ($vendor->locations as $loc)
{{$loc-id}}
#endforeach
However, I would like to simply json_encode only the id values for each of the locations. If possible, I would like to do so without creating a loop. So, I know I can do this:
{{json_encode($vendor->locations)}}
But as you can guess, this dumps out JSON data of all of the fields in the locations table.
I know I can modify my relationship to only include the ID fields, but I do not want to do this because I want to use the relationship elsewhere.
Is there a way to just grab the ID fields using something like:
{{json_encode($vendor->locations->id)}}
You can pluck the 'id' and convert it directly to json.
{{ $vendor->locations->pluck('id')->toJson() }}
This requires that $vendor->locations is a Collection.
You can use Laravel's pluck and json methods:
{{ $vendor->locations->pluck('id')->toJson() }}
You can refer to the documentation for more information:
https://laravel.com/docs/8.x/collections#method-tojson

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.

Laravel Eloquent find and where return two different types?

When I use:
$myModel::find(1);
I'm completely fine using accessors, for example - that's because it returns an instance of the model?
And if I use
$myModel::where('foo', 'bar');
I can no longer access any accessors or model function, or even relationships on myModel Is that expected behavior and if it is - how should I execute a where query so I can keep using the model's relations?
you need to fetch the model.After that everything will work fine.
$myModel::where('foo', 'bar')->firstOrFail();

Eloquent : querying models depending on model's relationships

I'm looking for a way to query models depending on the existence of the model's relationships.
http://paste.laravel.com/xuh Here's a paste with what I'm looking to accomplish.
The basic idea would be to search for Collections only where the User has access in the shared_access table.
Dreamcode (doesn't work):
Collection::where('sharedAccess.user_id', '=', Auth::user()->id->get())
Check out the fancy has() method. It basically allows you to do things like this:
Collection::has('sharedAccess')->get();
That would fetch all collections that have a related SharedAccess instance.

Resources