Laravel get only users which they have specific Role using RelationShip - php

In my Laravel implemented web application i have Users and Roles tables with models which they are ManyToMany.
i want to get all users which they have specific role, for example:
$users = User::with(['roles' => function ($query) {
$query->whereLabel('is-portal-manager');
}])->get();
unfortunately this code return all users and compare role label and return that in relation ship array
Illuminate\Database\Eloquent\Collection {#2069 ▼
#items: array:3 [▼
0 => App\User {#2076 ▼
...
#relations: array:4 [▼
"properties" => null
"child" => Illuminate\Database\Eloquent\Collection {#2073 ▶}
"parent" => null
"roles" => Illuminate\Database\Eloquent\Collection {#2087 ▼
#items: array:1 [▼
0 => App\Entities\Role {#2074 ▼
...
#attributes: array:5 [▼
"id" => 1
...
"label" => "is-portal-manager"
...
]
...
}
]
}
]
...
}
1 => App\User {#2077 ▼
...
#relations: array:4 [▼
"roles" => Illuminate\Database\Eloquent\Collection {#2093 ▼
#items: []
}
]
...
}
]
}
as you can see in above output second user doesn't have any role and #items: [] is empty. i don't need to have this output structure and i want to have only which users have specific role, not all users with empty roles. second item of this collection shouldn't this output

Make your relationship conditional by using Laravel's whereHas:
$users = User::whereHas('roles', function ($query) {
$query->whereLabel('is-portal-manager');
})->with('roles')->get();
Official documentations for further reading on Eloquent Relationship Existence methods whereHas, has, doesntHave and whereDoesntHave

Related

Laravel WhereIn & With Query merge

so I’m running this query when a user selects multiple categories on the frontend of the site, I want it to bring back the products that are related to the selected categories… this works, however, I have 2 collections that I need to merge together. Here is the code:
$category = Category::whereIn('permalink', $request->get('categoryFilter'))->with('products')->get()->pluck('products');
I get the following back:
Illuminate\Support\Collection {#1779 ▼
#items: array:2 [▼
0 => Illuminate\Database\Eloquent\Collection {#1780 ▼
#items: []
#escapeWhenCastingToString: false
}
1 => Illuminate\Database\Eloquent\Collection {#1799 ▼
#items: array:24 [▶]
#escapeWhenCastingToString: false
}
]
#escapeWhenCastingToString: false
}
The first category has no products but the second has, is there a way of merging these 2 together?
Try this,
$category = Products::whereIn('category_id',Category::whereIn('permalink',
$request->get('categoryFilter')
)->pluck('id')
)->get();

How to display pagination links in a blade on Laravel 8?

I need to add pagination, but it seems complicated in my case, because I get data from database with paginate, but then I modify this data and when I call links() method on the blade, I get the following exception
Method Illuminate\Support\Collection::links does not exist.
My code in the Controller method:
$transactionsByLastMonth = Transaction::where('created_at', '>=', Carbon::now()->subDays(30)->toDateTimeString())
->where('user_id', Auth::user()->id)
->with(['user', 'propertyFrom', 'propertyTo', 'paddockFrom', 'paddockTo', 'cattleTypeFrom', 'cattleTypeTo'])
->paginate(10);
$transactionsByDays = collect(TransactionResource::collection($transactionsByLastMonth))
->sortByDesc('created_at')
->groupBy(function($date) {
return Carbon::parse($date['created_at'])->format('d');
});
return view('user.reports.index', compact('transactionsByDays'));
Yes, a pagination limits my data to 10 rows, but due to I'm grouping data by days, my collection modifies itself and I can't use $transactionsByDays->links() method to show pagination.
If see dd($transactionsByDays) , it looks like:
Illuminate\Support\Collection {#1381 ▼
#items: array:3 [▼
"01" => Illuminate\Support\Collection {#1019 ▼
#items: array:7 [▼
0 => array:16 [▶]
1 => array:16 [▶]
2 => array:16 [▶]
3 => array:16 [▶]
4 => array:16 [▶]
5 => array:16 [▶]
6 => array:16 [▶]
]
}
31 => Illuminate\Support\Collection {#1386 ▼
#items: array:2 [▼
0 => array:16 [▶]
1 => array:16 [▶]
]
}
30 => Illuminate\Support\Collection {#1384 ▼
#items: array:1 [▼
0 => array:16 [▶]
]
}
]
}
Therefore I need to paginate all arrays together which inside "01", 31, 30...
How can I do it?
Maybe rewrite code above in the controller somehow?
The main aim is that I need to group data to every day according to my json-resource class.
Any ideas?
I've found a solution gyus. I had to pass also a variable transactionsByLastMonth and use links() method over this.
In the meantime I use foreach on the my blade file over transactionsByDays variable. It's correctly works together cause it uses the same data from database, just in the first case its not filtered and not grouped and in the second one it is.
return view('user.reports.index', compact('transactionsByLastMonth', 'transactionsByDays'));

Laravel sync users to all of categoires which they can be unlimited

In our web application each user can create multiple nested category by selecting the parent which that specified with category_id column.
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('category_id')->index()->nullable();
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->string('category_name');
...
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
now you supposed one of our user created this category structure:
multiple nested categories children are unlimited, that means every category can be have child and we can't use any static or fixed number for example in for statement to sync the category to specify users.
my question is how can i set specify users to all of categories from parent?
this query only can set users for single child of parent. you can suppose 1,3,4,5,6,7 in above screen shot and not working for 2 and all of their children
children of parent category can be unlimited and how can we set users from the parent to all of nested and children categories?
$category = Category::whereId($request->category_id)->whereNull('category_id')->with('childrenCategories')->first();
$category->users()->sync($request->users);
foreach ($category->childrenCategories as $category) {
$category->users()->sync($request->users);
}
simplified output of query:
App\Entities\Category {#2114 ▼
...
#attributes: array:11 [▶]
#original: array:11 [▶]
...
#relations: array:1 [▼
"childrenCategories" => Illuminate\Database\Eloquent\Collection {#2118 ▼
#items: array:4 [▼
0 => App\Entities\Category {#2133 ▶}
1 => App\Entities\Category {#2134 ▶}
2 => App\Entities\Category {#2135 ▼
...
#attributes: array:11 [▶]
#original: array:11 [▶]
...
#relations: array:1 [▼
"categories" => Illuminate\Database\Eloquent\Collection {#2138 ▼
#items: array:1 [▼
0 => App\Entities\Category {#2157 ▼
...
#attributes: array:11 [▶]
#original: array:11 [▶]
...
#relations: []
...
}
]
}
]
...
}
3 => App\Entities\Category {#2136 ▶}
]
}
]
...
}
You have to use a recursive function like below:
private function syncCategories($category,$request){
if($category->childrenCategories->first()){
foreach ($category->childrenCategories as $childCategory) {
$childCategory->users()->sync($request->users);
$this->syncCategories($childCategory);
}
}
}

Get the limited items of each type grouped items laravel

I have a table called books and another table called categories and it has item_id, type , and others .. columns in categories and type in enum (1/2/3)
Now I am trying to get the limited items of each group like 3 items from each type
So for that I am trying to get the 9 categores 3 each which has different type
Like This
Illuminate\Database\Eloquent\Collection {#2067 ▼
#items: array:3 [▼
1 => Illuminate\Database\Eloquent\Collection {#2060 ▼
#items: array:3 [▶]
}
2 => Illuminate\Database\Eloquent\Collection {#2055 ▼
#items: array:3 [▶]
}
3 => Illuminate\Database\Eloquent\Collection {#2026 ▼
#items: array:3 [▶]
}
]
}
So far I have tried this with .
$categoryLists = Category::where('display_at_home', 1)->limit(3)->get()->grouBy('type');
But it is not doing the work
You can use the Eloquent Eager Limit package as follows.
class Book extends Model
{
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
...
}
class Category extends Model
{
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
...
}
Then to get the relation you desire, you can do:
$categoryLists = Category::where('display_at_home', 1)
->limit(3)
->with(['books' => function($query) {
$query->limit('3');
}])
->get();

Laravel collection pluck dropping a value

I have the following Eloquent query in a Laravel 5.2 project:
$regsByCtryCollection = Organisation::join('countries_currencies', 'countries_currencies.id', '=', 'organisations.country_id')
->select(DB::raw('DISTINCT LCASE(countries_currencies.country_code) AS ctry, COUNT(organisations.id) AS val'))
->groupBy('ctry')
->get();
The raw query produces this output:
ctry val
at 1
au 5
br 1
The Eloquent call produces a collection of three rows (matching raw query output) like this:
Collection {#791 ▼
#items: array:3 [▼
0 => Organisation {#777 ▼
#table: "organisations"
#hidden: []
........
#attributes: array:2 [▶]
#original: array:2 [▼
"ctry" => "at"
"val" => 1
]
#relations: array:5 [▶]
........
}
1 => Organisation {#778 ▶}
2 => Organisation {#779 ▶}
]
}
I then pluck the values and format for Highmaps like this
$regsByCtry = $regsByCtryCollection->pluck('ctry', 'val')->map(function($country, $value) {
return [
"hc-key" => $country,
"value" => $value
];
})->values()->toJson();
And one of the values is dropped and I get this:
[
{"hc-key":"br","value":1},
{"hc-key":"au","value":5}
]
Why is the first entry getting dropped?
{"hc-key":"at","value":1}
I am using this same process with two other Eloquent queries and it works as expected, but just not on this collection.
Additionally, I also sum all the values in the array of objects like this:
$regsTotal = array_sum($regsByCtryCollection->pluck('val')->toArray());
And I get the correct value, including all three records summed:
$regsTotal = 7;
The issue is with pluck('ctry', 'val'). This will return val as key & ctry as value. In your query output at & br has same value 1. So one of it getting replaced by the other one.
Try pluck('val', 'ctry')->map(function($value, $country)
Reference

Categories