I've followed this code structure for a multi-level category system on Laravel 5:
This works fine. But I'm trying to put together a query to return posts in a category (by slug) but also the children categories underneath.
So heres what I've got at the moment:
$posts = Post::with('images')->whereHas('categories', function($q) use ($slug)
{
$q->where('slug', '=', $slug);
})->orderBy('created_at', 'DESC')->paginate(10);
This returns everything under the category that matches the slug passed through, but not the children. Any suggestions?
Thanks.
If you have only one depth of subcategories, the following solution is what I would use.
<?php
$category = Category::where('slug',$slug)->first();
$posts = Post::with('images')->whereHas('categories', function($q) use ($category)
{
$q->where(function($q) use ($category) {
$q->where('id', $category->id)->orWhere('parent_id',$category->id);
});
})->orderBy('created_at', 'DESC')->paginate(10);
In your code, you only fetched the Posts and their images. If I understood correctly, what you want to fetch are the Posts, their images, the category their in and childCategories (this is a made up name) of that category. You just need to add category.childCategories in your with method like so:
$posts = Post::with('images', 'categories.childCategories')->whereHas('categories', function($q) use ($slug)
{
$q->where('slug', '=', $slug);
})->orderBy('created_at', 'DESC')->paginate(10);
Remember to change the childCategories name to whatever the child category relationship name in your Category model.
Related
Let's say I have Account and Product models. And I need to get all accounts with favorite products. $alert is boolean to get products with stock alerts. (just an example)
I want to get all accounts having at least one favorite product with alert and all their other favorite products. I am doing this:
...
$query = Account::where('active', true)->when($alert, function ($query) {
$query
->whereHas('products', function($query) {
$this->getThosesWithAlerts($query);
});
});
...
// get $query and make pagination...
I get column not found Account.id in my function "getThosesWithAlerts". I use this function in another query and it works perfectly.
When I use "with" only like:
...
$query = Account::where('active', true)->when($alert, function ($query) {
$query
->with(['products' => function($query) {
$this->getThosesWithAlerts($query);
}]);
});
...
// get $query and make pagination...
I have no error: I have accounts with only products with stock alert (not all); the pagination is broken, so it seems $query is not good for my pagination which works also for another query. It is global pagination for all projetcs queries.
What I want is all products of accounts for accounts having at least one product in alert. Adding with to whereHas in my initial request does not change anything to my error. Unknown column or not found column account.id. So whereHas is my issue but I need it.
...
$query = Account::where('active', true)->when($alert, function ($query) {
$query
->with('products')
->whereHas('products', function($query) {
$this->getThosesWithAlerts($query);
})
});
...
// get $query and make pagination...
what is wrong with whereHas and how to fix it?
I want to page the relation articles. The correct number is displayed but not in the collection, for example "first page" or "to last".
$articles = Categories::where('slug', $categorie)->with(['articles' => function ($query) use ($default_count, $default_sort) {
$query->orderBy('price', $default_sort)
->with('contents')
->paginate(2);
}])->first();
What am I missing here?
Try flipping it around so that Article is the top level:
$articles = Article::with('contents')
->whereHas('category', function ($query) use ($categorie) {
$query->where('slug', $categorie);
})
->orderBy('price', $default_sort)
->paginate(2);
This assumes that you have the category relationship set up on Article as well.
i think you want result some like that
Article::whereHas('category', function ($query) use ($categories) {
$query->where('slug', $categories);
})
->with('contents')
->orderBy('price', $default_sort)
->paginate(2);
I have a some problem with filter query. I need to do somethink like
select painting from artist_painting where type=$_GET['type'] AND material=$_GET['material'] and artist_slug =$_GET['artist_slug'] ORDER BY painting DESC
I have a pivot table artist_painting and artist. 'artist_slug' is in the 'artist' table
I do
$this['painting'] = Painting::whereHas('artist', function($q)
{
$q->where('artist_slug', '=', $this->param('slug'));
})->get();
but I do not know what to do next.
How can i do query in php code?
Short and dirty:
Painting::where('type',input("type"))
->where('material',input("material"))
->whereHas('artist', function($q)
{
$q->where('artist_slug', '=', $this->param('slug'));
})->get();
The explanation:
When you initialize a query a query builder instance is returned. Basically all methods on the query builder return the same instance so you can daisy chain them into one query.
But you can also just work on the query builder.
$query = Painting::where('type',input("type"));
or:
$query = $model->newQuery()// Where model is an intance of painting, for example new Painting();
Then you can just work on the query builder instance, pass it to other methods that might to do things.
function getPaintings($type, $material, $slug)
{
$query = Painting::where('type',$type);
$query->where('material', $material);
$this->findArtistBySlug($query, $slug);
return $query->get()
}
function findArtistBySlug($query, $slug)
{
$query->whereHas('artist', function($q) use ($slug)
{
$q->where('artist_slug', '=', $slug);
});
$query->with(['artist']);
}
You might want to read https://octobercms.com/docs/database/query
and https://laravel.com/docs/5.6/queries
I would solve this problem from the Artist's point of view:
$artist = Artists::where('artist_slug', $this->param('slug'))->with('paintings')->first();
All the paintings of the artist can be accessed by using $artist->paintings, which will be a Collection.
Hi all,
I'm building an application in Laravel, I want to get all item in an article category without using this Eloquent.
My code is
$info = Article::find($article_id);
$cate_info = $info->article_categories()->first();
if($cate_info){
$same = Article::with(['article_categories' => function ($query) use ($cate_info){
$query->where('articles_category.ID' ,$cate_info->ID);
}])->where('ID' ,'!=' ,$article_id)->get();
}
And I get all articles. How to solve.
Article and Article_Category is in many to many relationship.
Thanks.
If you want to have all the articles of a particular article_categories you can use whereHas method, now suppose you have name as a field column in categories table, so you can have something like this:
public function getData(Request $request)
{
$category = $request->categoryName;
// $category = 'ABC Category';
$articles = Article::whereHas('article_categories', function($query) use($category) {
$query->where('name', 'like', '%'.$category.'%');
})->get();
return response()->json(['articles' => $articles], 200);
}
Hope this helps.
I am making an image gallery. Images have a many to many relationship with tags. Images also have a many to many relationship with catagories.
$images = $category->images;
$images = $tag->images;
public function images(Category $category = null)
{
$images = $category->images;
return view('pages.images.index', compact('images'));
}
Route model binding on this code works fine and I can do the same for tags but what I am looking to do is filter on category and then tag.
$images = $tag->category->images;
For example, if I had an image with the tag of "dog" and a category "brown" the query would only return all dogs that are brown.
Can I do this? Both tags and categories could have multiple options so I was hoping for a route like this...
mysite.com/images/{category}/{tag}
Thanks for any help or best direction to go.
You could use the build in laravel whereHas functionality
Image::whereHas('categories', function ($query) use ($category) {
$query->where('NAME', '=', $category);
})->whereHas('tags', function ($query) use ($tag) {
$query->where('NAME', '=', $tag);
})->get();
replace the NAME with the desired field you want to filter on.
You can declare the route just as you stated and then use them as parameters in the controller-method which is connected to the route.
So if you declare a route like Route::get('/register/{token1}/{token2}','RegisterController#confirm');then it is possible to get those wildcards in the method confirm just like normal parameters:
public function confirm(Request $request, $token1, $token2) {}