Reputation: 1211
I have the following tables
Recipe:
- id
- name
- image
Ingredients:
- id
- title
- image
(pivot) recipes_ingredients
- id
- recipe_id
- ingredients_id
votes:
- id
- rating
- recipe_id
How can I join over four tables?
What I need:
For each ingredient (which has flag == 1), I need 6 random recipes, which also have the votes in it.
Like
$ingredient->recipes
in a FOREACH and then $recipe->rating (<-- AVG(ranking))
This was my first attempt, but didn't work:
$ingredients = Ingredients::with('recipes')
->where('ingredients.is_product',1)
->where('recipes.status', '=', '1')
->join('ingredient_recipe', 'ingredient_recipe.ingredients_id', '=', 'ingredients.id')
->join('recipes', 'ingredient_recipe.recipe_id', '=', 'recipes.id')
->select(array('ingredients.*'))
->get();
based on this query:
$bestThreeRecipes = Recipe::with('user')
->where('recipes.status', '=', '1')
->join('votes', 'votes.recipe_id', '=', 'recipes.id')
->select(array('votes.*','recipes.*',DB::raw('AVG(rating) as ratings_average, COUNT(rating)')))
->groupBy('recipes.id')
->orderBy('ratings_average', 'DESC')
->get()->take(4);
(This works fine!)
Do you have an idea? Thank you!
EDIT #1:
Now I tried this:
$ingerdients = Ingredients::with(array('recipes','recipes.votes'))
->where('ingredients.is_product',1)
->where('recipes.status', '=', '1')
->join('ingredient_recipe', 'ingredient_recipe.ingredients_id', '=', 'ingredients.id')
->join('recipes', 'ingredient_recipe.recipe_id', '=', 'recipes.id')
->select(array('ingredients.*'))
->get();
But I still don't know how to get the AVG() working just for the recipes!
EDIT #2 - Solution (for now):
This seems to work, thanks to deczo!
$ingredients = Ingredients::with(array(
'recipes' => function ($q) {
$q->where('recipes.status', '=', '1')
->join('votes','recipes.id','=','votes.recipe_id')
->select(DB::raw('avg(rating) AS rating'))->groupBy('recipes.id')->orderBy('rating', 'DESC');
}))
->where('ingredients.is_product',1)
->get();
Upvotes: 0
Views: 205
Reputation: 81147
This should do the trick:
$ingredients = Ingredients::with(array(
'recipes' => function ($q) {
$q->where('recipes.status', '=', '1')
->join(
DB::raw('(SELECT AVG(rating) as rating, COUNT(rating) as ratingCount, id from votes group by recipe_id) as votes'),
'recipes.id',
'=',
'votes.recipe_id')
->select('votes.rating', 'votes.ratingCount');
}))
->where('ingredients.is_product',1)
->get();
Upvotes: 1