This is my first ever Laravel project, please bear with us. I am trying to display a parent->child hierarchy (not recursive), something akin to below:
I can't get my head around how to write the query to get the resources linked to the subStatement, not the top category, basically, an inner join related to SubStatement. It is currently displayed as so;
{
"id": 1,
"name": "Category 1: Practising plumbing overview",
"description": "<p>Category 1: Practising plumbing overview</p>",
"created_at": "2022-01-06 15:48:49",
"updated_at": "2022-01-06 15:48:49",
"deleted_at": null,
"plumbing_area_id": 1,
"category_id": 1,
"SubStatement": [
{
"id": 1,
"title": "Plying narrative for Category 1",
"description": "<p>Body of content.</p>",
"theme_id": 1,
"plumbing_area_id": 1
},
{
"id": 2,
"title": "Lay narrative for Category 1",
"description": "<p>body description.</p>",
"theme_id": 1,
"plumbing_area_id": 1
}
],
"resources": []
},
{
"id": 2,
"name": "Category 2: AAV Practising plumbing introduction",
"description": "<p><strong>Category 2:</strong> AAV Practising plumbing introduction</p>",
"created_at": "2022-01-06 15:49:12",
"updated_at": "2022-01-06 15:49:12",
"deleted_at": null,
"plumbing_area_id": 1,
"category_id": 1,
"SubStatement": [
{
"id": 3,
"title": "Plying narrative for Category 2",
"description": "<p>Body of content;</p>",
"theme_id": 2,
"plumbing_area_id": 1
},
{
"id": 4,
"title": "Lay narrative for Category 2",
"description": "<p>Body of content</p>",
"theme_id": 2,
"plumbing_area_id": 1
}
],
"resources": []
},
{
"id": 3,
"name": "Category 3: AAV Practising plumbing design",
"description": "<p><strong>Category 3: </strong>AAV Practising plumbing design</p>",
"created_at": "2022-01-06 15:49:47",
"updated_at": "2022-01-06 15:49:47",
"deleted_at": null,
"plumbing_area_id": 1,
"category_id": 1,
"SubStatement": [
{
"id": 5,
"title": "Plying narrative for Category 3",
"description": "<p>Body of content;</p>",
"theme_id": 3,
"plumbing_area_id": 1
},
{
"id": 6,
"title": "Lay narrative for Category 3",
"description": “Blah blah</p>",
"theme_id": 3,
"plumbing_area_id": 1
}
],
"resources": []
},
{
"id": 4,
"name": "Category 4: another “category,
"description": “Body</p>",
"created_at": "2022-01-06 15:50:04",
"updated_at": "2022-01-06 15:50:04",
"deleted_at": null,
"plumbing_area_id": 1,
"category_id": 1,
"SubStatement": [
{
"id": 7,
"title": "Plying narrative for Category 4",
"description": "<p>sdfsdfsdf;</p>",
"theme_id": 4,
"plumbing_area_id": 1
},
{
"id": 8,
"title": "Lay narrative for Category 4",
"description": "<p> sdfsdfsdfsdf</p>",
"theme_id": 4,
"plumbing_area_id": 1
}
],
"resources": []
},
]
I am looking for something like below instead, please note where the resource node is:
[
{
"id": 1,
"name": "Category 1: Practising plumbing overview",
"description": "<p>Category 1: Practising plumbing overview</p>",
"created_at": "2022-01-06 15:48:49",
"updated_at": "2022-01-06 15:48:49",
"deleted_at": null,
"plumbing_area_id": 1,
"category_id": 1,
"SubStatement": [
{
"id": 1,
"title": "Plying narrative for Category 1",
"description": "<p>Body of content.</p>",
"theme_id": 1,
"plumbing_area_id": 1,
"resources": [
{
"id": 1,
"resource_title": "The name of the resource"
}
]
}
]
}
]
//Themes Model
{
return $this->hasMany(Statement::class, 'theme_id', 'id');
}
public function resources()
{
return $this->belongsToMany(Resource::class);
}
//the Controller below is outputting the the JSON above
{
$output = Theme::where ( 'category_id', '=', $category_id )
->with(['subStatement' =>
fn ($query) =>
$query->select('id','title','description','theme_id','therapy_area_id')
])
->with(['resources' =>
fn ($query) =>
$query->select('id','temporary_url')])
->get();
}
// I attempted writing something like this. It threw a "Integrity constraint violation: 1052 Column 'id' in field list is ambiguous" error
{
return $this->hasOneThrough(Statement::class, Resource::class);
}
Your main issue is that you need to nest the query.
I will first adding the relationships to your models according to your schema.
Then, I will add the base query for the nesting if I understood what you're trying to achieve correctly.
Theme.php
public function subStatements()
{
return $this->hasMany(Statement::class); // 1-N
}
public function statements()
{
return $this->belongsToMany(Statement::class); // N-N
}
public function resources
{
return $this->belongsToMany(Resource::class); // N-N
}
Statement.php
public function theme()
{
return $this->belongsTo(Theme::class); // 1-N
}
public function themes()
{
return $this->belongsToMany(Theme::class); // N-N
}
public function resources
{
return $this->belongsToMany(Resource::class); // N-N
}
Resource.php
public function themes()
{
return $this->belongsToMany(Theme::class); // N-N
}
public function statements()
{
return $this->belongsToMany(Statement::class); // N-N
}
$themes = Theme::query()
->where('category_id', $category_id)
->with([
'subStatements' => fn ($query) => $query->with('resources')
])
->get();