Building query to select from 3 tables in Laravel - php

Normally I know how to query and join three tables but here I can't figured it how to happen. The thing is that I have followed 3 tables:
category -> columns
id
name
image
sub-category -> columns
id
table1_id
name
image
Sub-sub-category -> columns
id
table2_id
name
image
So image can be added only to Category or to Category->Sub-Category or to third level Category->Sub-Category->Sub-Sub-Category
What I'm trying to do is when I show ALL images on page to show also to which category they are added.
I've made all relations in my models but I can't figured it out how to query exactly. Currently only querying all images like
SubSubCategories::all();
Example:
I have main category(Country) which has sub-category (district) which has sub-sub-category(city).
image1 is added to Sub-Sub-Category with name city. When images are listed I want to show
images1 added to Country->District->City.
Can someone show me example query or maybe my relations eg. columns in tables are wrong?
This is what I've tried so far
$subsubcategories = DB::table('sub_sub_category')
->join('sub_category', 'sub_sub_category.sub_cat_id', '=', 'sub_category.sub_cat_id')
->join('category', 'category.category_id', '=', 'sub_category.sub_cat_id')
->select('sib_sub_category.*', 'sub_category.*', 'category.*')
->get();
Then in my view
{{ $subsubcategory->sub_category->sub_cat_name }} > {{ $subsubcategory->sub_sub_cat_name }}
error
Undefined property: stdClass::$sub_category

$subsubcategories = DB::table('category')
->join('category', 'category.id', '=', 'sub_category.table1_id')
->join('sub_category', 'sub_category.id', '=', 'sub_sub_category.table2_id')
->select('category.*', 'sub_category.*', 'sub_sub_category.*')
->get();

Actually you are almost there. Just remove the sub_category from the view and will work.
{{ $subsubcategory->sub_cat_name }} > {{ $subsubcategory->sub_sub_cat_name }}
This is happen because your array currently is looks like
object(stdClass) {
["id"]=> int(1)
["table2_id"]=> int(1)
["table1_id"]=> int(1)
...
// all other columns
}
So actually they belongs to $subsubcategory and no need to bring sub_category and category in the view. Just display them in your $subsubcategory.

Related

Laravel sort child relationship collection

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');

Laravel leftJoin now showing results

I'm newbie on laravel and lerning leftJoin.
I have table called "users" with row "steam_id".
I have another table called "matches". "matches" table have a unique row called
"match_id".
Last one table called "match_players" have row called "match_id" aswell and "steam_id.
"match_id" same as table row "matches -> match_id".
I need take out info by using user steam_id by match_id from matches.
Controller:
$user->LatestMatches = DB::table('match_players AS mp')
->leftJoin('matches AS ma', 'ma.match_id', '=', 'mp.match_id')
->where('mp.steam_id', '=', $user->steam_id)
->where('team', '=', 2)
->where('team', '=', 1)
->select("mp.*", "ma.map")
->get('');
Blade:
#foreach ($user->LatestMatches as $lastmatch)
{{ $lastmatch->map }}
#endforeach
But dont getting any info. Sorry if u don`t understand what i need todo. Thanks for replies and helping me understanding laravel!
->where('team', '=', 1)->where('team', '=', 2) doesn't work because it selects players who are in team 1 AND team 2 at the same time. No player can fulfill this constraint.
Use ->whereIn('team', [1, 2]) instead. This selects players who are in team 1 OR team 2.

Laravel group by foreign key

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.

How to write query to get result form multiple tables in laravel

I am doing project in laravel. There are two tables "categories" and "subcategories". "subcategories" table have categoryid as a foreign key.
I want to fetch categoryname from categories table and subcategoryid,subcategoryname from subcategories table where categoryid = $categoryid.
Here is something what I did. $cat contains many categoryid's but, from this I got only subcategories details,
foreach($cat as $categoryid){
$subcategories[] = Subcategory::where('categoryid', '=', $categoryid)->get();
}
I am not getting how to do this,please help.

Laravel 4: selection many to many relation

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,

Categories