hello I have two tables one is categories another is ads_listings. In categories table there are 4 columns id, parent_category_id, category_slug, category_title. Here parent_category_id 0 indicates main category and rest of the thing indicates sub category. user post store in ads_listings table. Now I want to find post with specific categories like this
vehicles(3)
cars(2)
motorbike(1)
cycle(0)
here the problem is my code found only subcategories which have posts. my controller code is
public function countListingsByCategories()
{
return DB::table("ads_listings")
->select("categories.category_title",DB::raw("COUNT(ads_listings.category_id) as num_listings"))
->join("categories", "categories.id","=","ads_listings.category_id")
->groupBy("ads_listings.category_id")
->get();
}
views code is:
<ul class="row catelist">
#if(isset($categoriesNumListings) && count($categoriesNumListings))
#foreach($categoriesNumListings as $categoriesNumListings)
<li class="col-md-12">{{ $categoriesNumListings->category_title }} <span>({{ $categoriesNumListings->num_listings }}Listings )</span></li>
#endforeach
#endif
</ul>
my Category table is:
ads_listing table is:
I think the problem is that you are counting ad_listings when you primarily want to count categories and get the number of ad_listings, I would do something like:
Second shot :)
public function countListingsByCategories()
{
return DB::table("categories")
->select("categories.category_title",
DB::raw("categories.title,
CASE
WHEN (categories.parent_id = 0)
THEN (SELECT count(ads_listings.category_id)
FROM ads_listings
WHERE ads_listings.category_id in
(SELECT subcategory.id
FROM categories subcategory
WHERE subcategory.parent_id = categories.id))
ELSE (SELECT COUNT(ads_listings.category_id)
FROM ads_listings
WHERE ads_listings.category_id = categories.id)
END as numberOfPosts,
CASE
WHEN (categories.parent_id = 0)
THEN (select 'Category')
ELSE (select 'subCategory')
END as type
FROM categories"))
->get();
}
Related
I am using this query to get the children of each category
$this['children'] = Cat::first()->children;
But it only gets the subcategories of of the first category and the same subcategories appear for all other categories. Any ideas on how t fix this?
Model relation
public function children(){
return $this->hasMany(static::class,'parent_id','id');
Table structure
category table
id
cat_title
parent_id
nest_right
nest_left
nest_depth
slug
parent_id = 0(category)
parent_id > 0(subcategory)
To get sub-categories of each category you first need to get the id of each category and use it in you query. (e.g. in a foreach loop)
$this['children'] = Cat::find($id)->children;
If you need to get all the categories with their related subcategories at the same time you need to eager load:
$allCatsWithTheirChildren = Cat::with('children')->all();
I have the following 3 tables:
Movie
- id
Series
- id
- status_id
- movie_id
Status
- id
- order_number
this is the code on the controller:
$movie = Movie::where('slug', $slug)->with(['series'])->first();
this is the code for view:
#foreach ($movie->series as $series)
{{ $series->name}}
#endforeach
how to sort $movie->series based on status->order_number? if it can be written on the model, so every order is only written once the controller?
is there a code that I can use for example like this:
$movie->series->sortBy('status.order_number');
Yes, but you will need to join status with series:
$movie = Movie::where('slug', $slug)->with([
'series' => function ($query) {
// Subquery on `series` table
return $query
// select whatever you'll need
->select('series.*')
// join with status
->join('status', 'series.status_id', '=', 'status.id')
// order by order number
->orderBy('status.order_number')
// * you can drop this if you select all the fields you need and use those
->with('status');
},
])->first();
Edit this ^ method will sort on SQL level, but you could also do this with collections:
#foreach ($movie->series->sortBy('status.order_number') as $series)
{{ $series->name}}
#endforeach
In that case also add .status to your with to avoid n + 1 problem: ->with(['series.status'])
The reason your attempt didn't work is because ->sortBy(..) doesn't mutate the collection, it just returns a new sorted one. This would work:
$movie->series = $movie->series->sortBy('status.order_number');
I have three models related through hasMany relationship: Course/Lesson/Article - A Course hasMany Lessons which hasMany Articles.
I have an int column in my articles table named pos (short for position) and I want to order the articles by it.
I am using the following query in my CoursesController, but it's not sorting the articles by this pos attribute:
Code:
public function show(Course $course, Lesson $lessons, Article $articles)
{
$articles = $lesson->articles()->orderBy('pos', 'asc')->get();
return view('users.courses.show', compact('course', 'lessons', 'articles'));
}
I'm using a foreach loop in blade:
#foreach($lesson->articles as $article)
{{ $article->title }}
#endforeach
Any help would be appreciated!
Laravel debugbar shows the following result:
select * from articles where slug = 'this-is-article-one' limit 1
13.27ms\vendor\laravel\framework\src\Illuminate\Routing\ImplicitRouteBinding.php:35
select * from articles where lesson_id = 1 and pos < 2 order by pos desc limit 1 660μs\app\Http\Controllers\Users\ArticlesController.php:55
select * from articles where lesson_id = 1 and pos > 2 order by pos asc limit 1 520μs \app\Http\Controllers\Users\ArticlesController.php:59
select * from courses where courses.id = 2 limit 1 610μs view::users.articles.show:7
select * from lessons where lessons.id = 1 limit 1 530μs
view::users.articles.show:8
select * from articles where articles.lesson_id = 1 and articles.lesson_id is not null
When you call $lesson->articles again in the show view, basically you make a new DB call. To get the correct values, use the variable $articles:
#foreach($articles as $article)
{{ $article->title }}
#endforeach
If you want to continue using your lesson object in your view, use sortBy:
#foreach($lesson->articles->sortBy('pos') as $article)
{{ $article->title }}
#endforeach
I will suggest to extend you relationship with orderBy()
<?php
public function articles(){
return $this->hasMany('App\Articles')->orderBy('pos','asc');
}
I have three models
Project
Category
Drawing
The relationship between them is as follows
Drawing belongs to a category
Drawing also belongs to a project
Drawing table:
id
name
project_id
category_id
Project Table :
id
name
Category Table :
id
name
I want to print all the drawings of a particular project grouped by category name like so :
CATEGORY X
* Drawing 1
* Drawing 2
CATEGORY Y
* Drawing 3
* Drawing 4
I do not want to print a category if there is no drawing for this particular project in it.
this is what im stuck at :
Project->drawings()->groupBy('category_id');
Thank you in advance
To get the output you want, it'd be easier to come at the problem from the direction of categories.
The following will find all categories, with drawings belonging to the specified $projectId, but only those categories that actually have one or more drawings.
$projectId = 123;
$projectScope = function ($query) use ($projectId) {
return $query->where('project_id', $projectId)
});
$categories = Category::with(['drawings' => $projectScope])
->whereHas('drawings', $projectScope)
->get();
You can do it like
$categories = Category::whereIn('id',$project->drawings()
->groupBy('category_id')
->pluck('category_id')
)->get();
Now, Iterate over $categories like
#foreach($categories as $category)
// display category name as {{$category->name}}
#foreach($category->drawings() as $drawing)
// display drawings as {{$drawing->name}}
#endforeach
#endfoeach
Hope you understand.
I work on a blog project, which have relation many to many between "posts" and "cats" tables (with pivote table)
posts:
id
title
topic
cats:
id
name
cat_post:
post_id
cat_id
I prepare models correctly,
so, how to select all posts in specific category? I tried:
Cat::with('post')->where('id', '=', '3')->get();
and
Post::with('cat')->whereId('3')->get();
but nothing yet,
This is better/shorter:
$cats = Cat::with('post')->find(3);
Update:
$cats = Cat::with(array('post' => function($q) { // make sure posts not post
$q->orderBy('id', 'desc'); // order the posts
}))->find(3); // No need to order a single model
just found the answer
$cats = Cat::with('post')->whereId(3)->first();
then retrive it in blade:
#foreach($cats->post as $post)
{{$post->title}}
#endforeach
thanks,