我有三张表garages
,cars
,securities
。
证券是保证一辆车安全的证券,您可以拥有多个证券,但单一证券只能保证一辆车安全。车库是汽车的所在地,也是证券。
我想要的是列出所有证券并知道他所在车库的名称。问题是securities
没有包含车库id的列,只有他保持安全的汽车的id,但汽车有车库的id。
Laravel Eloquent有一个名为hasManyThrough
的方法,但securities
只有一个garage
到cars
。
以下是表格:
车库表:
-----------------------------------
|garage_id|garage_name|garage_size|
-----------------------------------
| 1| Garage 1| 200|
-----------------------------------
| 2| Garage 2| 400|
-----------------------------------
汽车表:
---------------------------
|car_id|car_name|garage_id|
---------------------------
| 1| Car 1| 1|
---------------------------
| 2| Car 2| 1|
---------------------------
| 3| Car 3| 2|
---------------------------
证券表:
----------------------------------
|security_id|security_name|car_id|
----------------------------------
| 1| Security 1| 1|
----------------------------------
| 2| Security 2| 1|
----------------------------------
| 3| Security 3| 2|
----------------------------------
| 4| Security 4| 3|
----------------------------------
输出必须是:
Security 1 is on Garage 1
Security 2 is on Garage 1
Security 3 is on Garage 1
Security 4 is on Garage 2
我有模特:
代码是列出车库,但我想做类似但列出证券(只是为了让你知道结构是如何)。
$garages = Garages::with(['cars', 'securities'])->get();
$garages->transform(function($garages) {
return array(
'garage_name' => $garage->garage_name,
'count_cars' => $garage->cars->count(),
'count_securities' => $garage->securities->count(),
);
});
class Garages extends Eloquent
{
public function cars()
{
return $this->hasMany('cars');
}
public function securities()
{
return $this->hasMany('securities');
}
}
class Cars extends Eloquent
{
}
class Securities extends Eloquent
{
}
再强调一下:我希望车库的名称与安全保障安全的汽车相关。
如果我这样做,只是为了让它更容易理解:
$securities = Securities::with(['cars'])->get();
class Securities extends Eloquent
{
public function cars()
{
return $this->hasOne('cars');
}
}
我将只从garage_id
表中获取cars
作为关系。我真正想要的是车库的名称。
[relations:protected] => Array
(
[cars] => Cars Object
(
...
[attributes:protected] => Array
(
...
[car_name] => Car 1
[garage_id] => 1
...
答案 0 :(得分:31)
看起来您没有正确地关联对象。让我们打破这一点:
如果Garage
有很多Car
然后Car
属于Garage
,请继续考虑这个想法。
Garage
有很多Car
Car
有很多Security
Security
属于Car
Garage
有很多Security
到Car
在Eloquent中,您可以继续拍下这些关系,它应该适用于您在上面发布的架构。
class Garage extends Eloquent
{
public function cars()
{
return $this->hasMany('cars');
}
public function securities()
{
return $this->hasManyThrough('Security', 'Car');
}
}
class Car extends Eloquent
{
public function securities()
{
return $this->hasMany('Security');
}
// ADDED IN SECOND EDIT
public function garage()
{
return $this->belongsTo('Garage');
}
}
class Security extends Eloquent
{
public function car()
{
return $this->belongsTo('Car');
}
}
那应该是它。
编辑:只要有一条路径可以使用这些关系的组合从一个模型绘制到另一个模型,您就可以从任何模型访问所有这些关系。请查看以下内容:
$security = Security::with('car.garage')->first();
将检索第一个Security
记录并在其上加载Car
关系,然后再向步骤加载Garage
个关联,加载在{{{}下加载的每个Car
对象上1}}模型。
您可以使用以下语法访问它们:
Security
此外,请注意关系对象是$security->car->garage->id
// Other examples
$garage = Garage::with('cars.securities')->first();
foreach($garage->cars as $car)
{
foreach($cars->securities as $security)
{
echo "Car {$car->id} has {$security->id} assigned to it";
}
}
的一个实例,因此您可以使用Collection
,->each()
,->count()
等所有精美方法。< / p>
答案 1 :(得分:14)
我最近遇到了类似的问题,并且能够做到这样的事情:
class Cars extends Eloquent
{
public function garage()
{
return $this->hasOne('Garages');
}
}
class Securities extends Eloquent
{
public function car()
{
return $this->hasOne('Cars');
}
public function garage()
{
return $this->car->garage();
}
}
这使您获得证券有一个车库关系,您可以做类似的事情:
$securities = Securities::with('garage')->get();
foreach($securities as $security)
{
echo $security->security_name . ' is on ' . $security->garage->garage_name;
}
答案 2 :(得分:6)
答案 3 :(得分:0)
您可以使用集成在Laravel => 5.8上的hasOneThrough
。
public function garage()
{
return $this->hasOneThrough(
Garage::class,
Car::class,
'car_id',
'id',
null,
'garage_id'
);
}
不要使用类似的解决方案
return $this->car->garage();
因为它正在使用紧急加载,并且您在每次迭代时都调用数据库。这些类型的解决方案尚未优化。