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();
Related
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'));
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
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();
Possibly an obvious one, but here it is:
After dd'ing a query result, I have:
$items = DB::table('my_table')->get(['id']);
dd($items);
Which results in:
Collection {#228 ▼
#items: array:1 [▼
0 => {#227 ▼
+"id": 2
}
]
}
Then, when I try to flatten it, it ignores me:
dd($items->flatten());
Resulting in:
Collection {#209 ▼
#items: array:1 [▼
0 => {#227 ▼
+"id": 2
}
]
}
Shouldn't I receive something like the flattened version of the collection?
How can I do it?
Thanks in advance.
You need to check it like
$flattened = $items->flatten();
dd($flattened->all());
// or dd($items->flatten()->all());
Source from official documentation.
If you want to fetch id and completely flatten then use
$items = DB::table('my_table')->pluck('id');
dd($items);
Here is the pluck link.
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