简体   繁体   English

Laravel 5如何使用链接检索相关的表数据

[英]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), and Rental_Location (list of rental addresses + lat/long). 我有地区(城市列表),租赁(租赁信息列表)和Rental_Location(租赁地址列表+纬度/长)的数据库表。

The basic relationships are: 基本关系是:

Regions haveMany Rentals (with FK's region_id and rental_location_id in Rentals table)
Locations haveMany Rentals, or the reverse logic Rental belongsTo a Location

What I'd like to do is get the location information of all the rentals in a region from a region_id (from the rentals table), as well as include the location spatial data (rental_locations table): 我想要做的是从region_id(来自租赁表)获取区域中所有租赁的位置信息,以及包括位置空间数据(rental_locations表):

$region = Region::find(1);
$rentals = $region->rentals; // doesn't contain location information yet
$rentalDataWithSpatialLocationData = $region->rentals->location; // what I liked to do 

But the last line using the belongsTo relationship won't work by adding the spatial data from rental_locations into the original rentals collection. 但是使用belongsTo关系的最后一行将无法通过将rental_locations中的空间数据添加到原始租赁集合中。

Right now the $rentals collection contains all the rentals for a region, but no spatial data to mark the location on a map, but other than using a join in QueryBuilder something like this below and not using the ORM hasMany properties in my models: 现在$ rental集合包含一个区域的所有租赁,但没有空间数据来标记地图上的位置,但除了在QueryBuilder中使用如下所示的连接而不在我的模型中使用ORM hasMany属性:

$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, I can't figure out how to get a collection of all the rentals with their location information, is this possible using the ORM? 基本上,我无法弄清楚如何使用其位置信息获取所有租赁的集合,这是否可以使用ORM? Seems like this might get expensive compared to a join, so I'm assuming right now you don't use the ORM to the exclusion of the QueryBuilder, but more to supplement simple and quick relationships queries only? 看起来这样比连接可能会变得昂贵,所以我现在假设您不使用ORM来排除QueryBuilder,而只是补充简单和快速的关系查询?

There are a couple things going on here that you should know about. 这里有几件你应该知道的事情。

First, for your original issue, your code won't work because you're trying to access the relationship attribute on a Collection of rental models, and not an individual model. 首先,对于您的原始问题,您的代码将无法运行,因为您尝试访问租赁模型Collection上的关系属性,而不是单个模型。 If you loop through the Collection , you would be able to access the location relationship on each individual item just fine: 如果您遍历Collection ,您将能够很好地访问每个单独项目上的location关系:

$region = Region::find(1);
$rentals = $region->rentals; // Collection of rentals for the region
foreach($rentals as $rental) {
    print_r($rental->location); // location info for the individual rental
}

Now, one thing to note about the code above is that you will be running into what is known as the N+1 problem. 现在,有关上述代码的一点需要注意的是,您将遇到所谓的N + 1问题。 By default, Laravel lazy loads the relationship objects, so the queries to populate the relationship data are not run until the relationship attributes are needed. 默认情况下,Laravel延迟加载关系对象,因此在需要关系属性之前,不会运行填充关系数据的查询。 Ignoring the region for right now, in the code above, Laravel will run one query to get all the rentals, and then in the foreach loop, it will run a new query for each loop iteration (N queries) to get the location information for each rental; 暂时忽略该区域,在上面的代码中,Laravel将运行一个查询以获取所有租借,然后在foreach循环中,它将为每个循环迭代(N个查询)运行新查询以获取位置信息每次出租; hence N+1 queries. 因此N + 1个查询。

To alleviate this problem, you can eager load the relationships. 要缓解此问题,您可以急切加载关系。 By eager loading, Laravel will run one query to get the rentals, and then one query to get all the location information for all the rentals, for a total of two queries (instead of N+1). 通过急切加载,Laravel将运行一个查询来获取租金,然后运行一个查询以获取所有租赁的所有位置信息,总共两个查询(而不是N + 1)。 Throw the region information back in there and it is actually three queries. 将区域信息重新放回那里,实际上是三个查询。

To eager load the relationships, you use the with() method on the query: 要急切加载关系,可以在查询中使用with()方法:

// eager load the rentals, and the nested location on the rentals
// 1 query for region, 1 for all rentals on region, and 1 for all locations on rentals
$region = Region::with('rentals', 'rentals.location')->find(1);

// this is now accessing already loaded rentals; no lazy loading needed
$rentals = $region->rentals;

foreach($rentals as $rental) {
    // this is now accessing already loaded locations; no lazy loading needed
    print_r($rental->location);
}

Another difference this makes, and what may have made you think you didn't have access to the location information, is that lazy loaded relationships won't show up until you access them, whereas eager loaded relationships are immediately available. 这样做的另一个不同之处是,您可能认为自己无法访问位置信息,因为延迟加载的关系在您访问它们之前不会显示,而急切加载的关系立即可用。 When debugging by printing the objects to the screen, this could make you think you're missing data when you're really not. 通过将对象打印到屏幕进行调试时,这可能会让您认为当您真的没有时会丢失数据。 What I mean by that is this: 我的意思是:

/**
 * lazy load relationships
 * This will only show the information for the region object. No
 * rental or location information will be shown as it has not been
 * loaded yet.
 */
$region = Region::find(1);
print_r($region);

/**
 * eager load relationships
 * This will show the information for the region object, as well as
 * all of the related rental objects and their related location
 * information.
 */
$region = Region::with('rentals', 'rentals.location')->find(1);
print_r($region);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从Laravel中的多个相关表中检索数据 - Retrieve data from multiple related table in laravel 使用Laravel 4检索相关模型 - Retrieve Related Models using Laravel 4 如何使用 Laravel 检索数据 - how to retrieve data using laravel 从3个表中检索数据如何在Laravel中使用第一个表从最后一个表中检索数据 - retrieve data from 3 tables How to retrieve data from the last table using the first one in Laravel 使用join的Eloquent查询来检索数据透视表和相关数据 - Eloquent query using join to retrieve pivot table and related data 如何使用updateOrCreate函数将一个json文件中的数据插入laravel中具有相关数据的多个表中? - how to insert the data from one json file to many table in laravel that have related data using updateOrCreate function? 在laravel中获取相关的表数据 - Get related table data in laravel 如何构建雄辩的查询以检索主表的记录,在Laravel 5 PHP中对其相关表应用where子句? - How to build Eloquent query to retrieve records of the main table, applying where clause on it's related table in Laravel 5 PHP? 如何在Laravel中使用关系检索数据 - how to retrieve data using relationship in laravel 如何使用cakephp从两个相关的表中检索数据? - How to retrieve data from two related tables using cakephp?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM