I want to be able to order my articles based on their rating which I solved using the following query:
return Article::where('private', 0)
->whereIn('movie_id', $movie)
->with(['user', 'movie', 'ratings'])
->withCount(['ratings as average' => function ($query) {
$query->select(\DB::raw('coalesce(avg(value), 0)'));
}])
->orderByDesc('average')
->paginate(10);
The problem is however if an article only has 1 or 2 ratings/votes and they are all positive ratings then the article will rank with other top articles that have many more ratings/votes which gives inaccurate results. How would I limit it only to articles with let's say more than 5 votes? Is there any other other better solution?
If ratings is a relation hasMany, you can simply use :
return Article::where('private', 0)
->has('ratings', '>=', 5)
...
To only get articles with 5 or more ratings.
You can grab all articles too in your query, with number of ratings :
return Article::where('private', 0)
->withCount('ratings')
...
And you can use a simple condition in your loop to show ratings only for Articles with 5 or more ratings :
#foreach ($articles as $article)
#if ($article->count_ratings >= 5)
// show rating
#endif
#endforeach
Related
I'm trying to retrieve the number of likes and dislikes a post have.
I've the following table in database, in which I've like column which decides like or dislike. if it is 1 it means like if it is zero it means dislike.
Problem :
I'm trying to count the number of like(s) a post has and then show it for each post, I'm trying to achieve this using ternary operator but I'm getting 1 like and 1 dislike for every post which is wrong according to the above table data.
Is there anything I'm doing wrong, because I think the code should work .
Because for post_id 1 the number of likes should be 2 according to the table , but I get 1 like and 1 dislike for each post.
Code
This is the code I'm trying to get the number of likes and dislikes
#if(count( $post->likes()->where('$post->like'==1) )>=1 )
<small>{{ count($post->likes()->where('$post->like' ==1))>=1?count($post->likes()->where($post->like ==1)). ' Likes':count($post->likes()->where($post->like ==1)).'Dislike' }}</small>
#else
<small>// similary do this for dislikes when like column in the above table is 0</small>
#endif
</small>
You can use the count and withCount method from eloquent to make this easier for you
You can count the likes and dislikes in your controller like this:
$posts = App\Post::withCount([
'likes' => function ($query) {
$query->where('like', 1);
},
'likes as dislikes_count' => function ($query) {
$query->where('like', 0);
}
])->get();
Then you can those counts this in your blade like
Likes count: {{ $post->likes_count }}
Dislikes count: {{ $post->dislikes_count }}
I want to ask how to implement Laravel Query with Multiple Group Count Result.
Basically it display the result of each voters in a barangay or town. However, aside from it I want to display the counts of voters if they are supporter or not labaled as 0 or 1 in their status.
public function brgy()
{
$brgy = Voter::groupBy('brgy')
->selectRaw('count(*) as total, brgy')
->get();
return view('brgy', compact('brgy'));
}
Please help.
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');
}
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();
}