Look at https://laracasts.com/discuss/channels/eloquent/eloquent-relationships-still-not-understand
and
http://dsmithweb.com/itemized.png
and
http://laravel.io/forum/04-04-2015-looping-through-collection
There a $5000.00 tutorial for free.
OrderBy computed, related attribute
Setup:
I have a Product model and a Review model. Products can have many reviews and Reviews belong to one Product (this has been set up through the hasMany() and belongsTo() methods. Each review stores an associated user ID, a text review, and a rating (1-5 stars as an integer).
Task at hand:
I've been tasked with creating a table that lists all products with their attributes as well as the average score of the products ratings. Additionally, I need to order the table by each product's average score in descending order (best rated to worst rated), and because there are so many products in the list I need to paginate the entries.
Current implementation:
I'm using a package (willvincent/laravel-rateable) to manage the reviews/ratings for the product. It stores individual reviews as described and uses a computed attribute to return the average rating for each product:
public function getRatingAttribute() {
return $this->ratings()->avg('rating');
}
The query I'm using to get the posts unsuccessfully is:
return Products::with('ratings')->orderBy('rating')->paginate(20);
I'm thinking the issue is that 'rating' isn't an actual DB column so it's not going to know what to orderBy.
Any help greatly appreciated!
@jakec729 Try this:
$apps = DB::table('products')
->select('products.*')
->leftJoin('ratings', 'products.id', '=', 'ratings.rateable_id')
->addSelect(DB::raw('AVG(ratings.rating) as average_rating'))
->groupBy('products.id')
->orderBy('average_rating', 'desc')
->paginate(session('posts_per_page'));
That might fix your issue of the id going null on you. I suspect what was happening was that it was getting overridden by the id in the ratings table -- in the case of an unrated product, null.
This small change to your otherwise working query explicitly says just grab product table fields and the average rating.. not everything from both.
Please or to participate in this conversation.
