php - Laravel 5 How to retrieve related table data using chaining -


i've got db tables of region (list of cities), rental (list of rental information), , rental_location (list of rental addresses + lat/long).

the basic relationships are:

regions havemany rentals (with fk's region_id , rental_location_id in rentals table) locations havemany rentals, or reverse logic rental belongsto location 

what i'd location information of rentals in region region_id (from rentals table), include location spatial data (rental_locations table):

$region = region::find(1); $rentals = $region->rentals; // doesn't contain location information yet $rentaldatawithspatiallocationdata = $region->rentals->location; // liked  

but last line using belongsto relationship won't work adding spatial data rental_locations original rentals collection.

right $rentals collection contains rentals region, no spatial data mark location on map, other using join in querybuilder below , not using orm hasmany properties in models:

$spatials = db::table('rentals')               ->join('regions', 'rentals.region_id', '=', 'regions.id')               ->join('rental_locations', 'rentals.rental_location_id', '=', 'rental_locations.id')               ->where('rentals.region_id', '=', $region_id)               ->select('*')               ->get(); 

basically, can't figure out how collection of rentals location information, possible using orm? seems might expensive compared join, i'm assuming right don't use orm exclusion of querybuilder, more supplement simple , quick relationships queries only?

there couple things going on here should know about.

first, original issue, code won't work because you're trying access relationship attribute on collection of rental models, , not individual model. if loop through collection, able access location relationship on each individual item fine:

$region = region::find(1); $rentals = $region->rentals; // collection of rentals region foreach($rentals $rental) {     print_r($rental->location); // location info individual rental } 

now, 1 thing note code above running known n+1 problem. default, laravel lazy loads relationship objects, queries populate relationship data not run until relationship attributes needed. ignoring region right now, in code above, laravel run 1 query rentals, , in foreach loop, run new query each loop iteration (n queries) location information each rental; hence n+1 queries.

to alleviate problem, can eager load relationships. eager loading, laravel run 1 query rentals, , 1 query location information rentals, total of 2 queries (instead of n+1). throw region information in there , 3 queries.

to eager load relationships, use with() method on query:

// eager load rentals, , nested location on rentals // 1 query region, 1 rentals on region, , 1 locations on rentals $region = region::with('rentals', 'rentals.location')->find(1);  // accessing loaded rentals; no lazy loading needed $rentals = $region->rentals;  foreach($rentals $rental) {     // accessing loaded locations; no lazy loading needed     print_r($rental->location); } 

another difference makes, , may have made think didn't have access location information, lazy loaded relationships won't show until access them, whereas eager loaded relationships available. when debugging printing objects screen, make think you're missing data when you're not. mean this:

/**  * lazy load relationships  * show information region object. no  * rental or location information shown has not been  * loaded yet.  */ $region = region::find(1); print_r($region);  /**  * eager load relationships  * show information region object,  * of related rental objects , related location  * information.  */ $region = region::with('rentals', 'rentals.location')->find(1); print_r($region); 

Comments

Popular posts from this blog

Android : Making Listview full screen -

javascript - Parse JSON from the body of the POST -

javascript - Chrome Extension: Interacting with iframe embedded within popup -