try using hasManyThrough https://laravel.com/docs/5.1/eloquent-relationships
How to Query Distant Relations in Laravel?
Hi! This post is related to my other post but since I am asking a more specific question, I decided to create a new post. I have the following database structure:
The Database Tables
countries
- id
- name
- code
regions
- id
- name
- country_id
sub_regions
- id
- name
- region_id
greater_districts
- id
- name
- sub_region_id
districts
- id
- name
- greater_districts_id
congregations
- id
- name
- district_id
The Model Relationships
The models are set up in such a way that:
- Country has many Regions
- Region has many SubRegions
- SubRegion has many GreaterDistricts
- GreaterDistrict has many Districts
- District has many Congregations
If I want to list all Congregations in a particular Country or a particular Greater District. How do I query this in Laravel?
I also need to relate these models to my User model so that a user that is assigned to a Region can only access all sub regions, greater districts, districts, and congregations within that region. Or if assigned to a County, user can only access regions, sub regions, greater districts, districts, and congregations within that country.
So the table relationships and hierarchy must be properly established:
- country level
- region level
- sub region level
- greater district level
- district level
- congregation level
Thank you for the help.
I have decided to do away with the hasManyThroughs since I could not get them to work. I used join instead to query the list of congregations under a country. Here is a sample code:
$listAll = DB::table('countries')
->join('regions', 'countries.id', '=', 'regions.country_id')
->join('sub_regions', 'regions.id', '=', 'sub_regions.region_id')
->join('greater_districts', 'sub_regions.id', '=', 'greater_districts.sub_region_id')
->join('districts', 'greater_districts.id', '=', 'districts.greater_district_id')
->join('congregations', 'districts.id', '=', 'congregations.district_id')
->select('congregations.*', 'congregations.name')
->where('countries.id', '=', 17)
->get();
foreach ($listAll as $item) {
echo '<ul><li>' . $item->name . '</li></ul>';
}
De-normalizing is an option for better performance, but the setup of the districts and congregations are very dynamic and often change in 3 to 6 months. It would entail a lot of maintenance.
If you have a better way to do it... feel free to post it here.
Please or to participate in this conversation.