有一个通过 Laravel Eloquent
我有三个表garages
、cars
、securities
.
证券是保护一辆汽车的安全,您可以拥有多个安全,但一个安全只能保护一辆车.车库是汽车所在,证券也是.
我想要的是列出所有证券并知道他所在的车库的名称.问题是 securities
没有包含车库 id 的列,只有他保持安全的汽车的 id,但是 car 有车库的 id.
Laravel Eloquent 有一个名为 hasManyThrough
的方法,但 securities
只有一个 garage
到 cars
.>
这是表格:
车库表:
-----------------------------------|车库编号|车库名称|车库大小|---------------------|1|车库 1|200|---------------------|2|车库 2|400|---------------------
汽车表:
---------------------------|car_id|car_name|garage_id|---------------------------|1|车1|1|---------------------------|2|车2|1|---------------------------|3|车3|2|---------------------------
证券表:
-------------------|security_id|security_name|car_id|----------------------------------|1|安全 1|1|----------------------------------|2|安全2|1|----------------------------------|3|安全3|2|----------------------------------|4|安全 4|3|----------------------------------
输出必须是:
安全 1 在车库 1保安 2 在车库 1保安 3 在车库 1保安 4 在车库 2
我有模型:
代码是列出车库,但我想做类似但列出证券(只是为了让您了解结构如何).
$garages = Garages::with(['cars', 'securities'])->get();$garages->transform(function($garages) {返回数组('车库名称' =>$garage->garage_name,'count_cars' =>$garage->cars->count(),'count_securities' =>$garage->securities->count(),);});车库类扩展了 Eloquent{公共功能汽车(){返回 $this->hasMany('cars');}公共功能证券(){返回 $this->hasMany('证券');}}类 Cars 扩展了 Eloquent{}证券类扩展 Eloquent{}
再次强调:我想知道与保安人员保持安全的汽车相关的车库名称.
只是为了让它更容易理解,如果我这样做:
$securities = Securities::with(['cars'])->get();证券类扩展 Eloquent{公共功能汽车(){返回 $this->hasOne('cars');}}
我将仅从 cars
表中获取 garage_id
作为关系.我真正想要的是车库的名字.
[relations:protected] =>大批([汽车] =>汽车对象(...[属性:受保护] =>大批(...[汽车名称] =>车1[车库 ID] =>1...
解决方案 您似乎没有正确关联对象.让我们分解一下:
如果一个Garage
有很多Car
,那么一个Car
属于Garage
,让我们继续这个想法心.
车库
有很多汽车
Car
有很多Security
安全
属于汽车
Garage
通过Car
有很多
Security
在 Eloquent 中,您可以直接将这些关系添加进来,鉴于您在上面发布的架构,它应该可以工作.
class Garage 扩展了 Eloquent{公共功能汽车(){返回 $this->hasMany('cars');}公共功能证券(){返回 $this->hasManyThrough('Security', 'Car');}}类 Car 扩展了 Eloquent{公共功能证券(){返回 $this->hasMany('Security');}//在第二次编辑中添加公共功能车库(){返回 $this->belongsTo('Garage');}}类 Security 扩展了 Eloquent{公共函数 car(){返回 $this->belongsTo('Car');}}
应该就是这样了.
您可以从任何模型访问所有这些关系,只要有一条路径可以使用这些关系的组合从一个模型绘制到另一个模型.看看这个,例如:
$security = Security::with('car.garage')->first();
将检索第一个 Security
记录并在其上加载 Car
关系,然后再执行一步并在每个 Garage
关系上加载所有 Garage
关系code>Car 对象加载在 Security
模型下.
您可以使用以下语法访问它们:
$security->car->garage->id//其他例子$garage = Garage::with('cars.securities')->first();foreach($garage->cars as $car){foreach($cars-> 证券作为 $security){echo "汽车 {$car->id} 已分配给它 {$security->id}";}}
此外,请注意关系对象是 Collection
的实例,因此您拥有所有花哨的方法,例如 ->each()
、->;count()
, ->map()
可用.
I have three tables garages
, cars
, securities
.
The securities are the ones that is keeping one car safe, you can have more than one security, but a single security can keep only one car safe. The garage is where the car is and the securities are as well.
What I want is to list all the securities and know the name of the garage that he is. The problem is that securities
doesn't have a column containing the id of the garage, only the id of the car that he is keeping safe, but car has the id of the garage.
Laravel Eloquent has a method called hasManyThrough
, but securities
has one garage
through cars
only.
Here is the tables:
garages table:
-----------------------------------
|garage_id|garage_name|garage_size|
-----------------------------------
| 1| Garage 1| 200|
-----------------------------------
| 2| Garage 2| 400|
-----------------------------------
cars table:
---------------------------
|car_id|car_name|garage_id|
---------------------------
| 1| Car 1| 1|
---------------------------
| 2| Car 2| 1|
---------------------------
| 3| Car 3| 2|
---------------------------
securities table:
----------------------------------
|security_id|security_name|car_id|
----------------------------------
| 1| Security 1| 1|
----------------------------------
| 2| Security 2| 1|
----------------------------------
| 3| Security 3| 2|
----------------------------------
| 4| Security 4| 3|
----------------------------------
The output must to be:
Security 1 is on Garage 1
Security 2 is on Garage 1
Security 3 is on Garage 1
Security 4 is on Garage 2
And I have the models:
The code is to list the garages, but I want to make similar but to list the securities (just for you to have an idea of how the structure is).
$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
{
}
And just to make an emphasis again: I want to have the name of the garage related to the car that the security is keeping safe.
Just to make it even easier to understand, if I do this:
$securities = Securities::with(['cars'])->get();
class Securities extends Eloquent
{
public function cars()
{
return $this->hasOne('cars');
}
}
I will get only the garage_id
from cars
table as relations. What I really want is the name of the garage.
[relations:protected] => Array
(
[cars] => Cars Object
(
...
[attributes:protected] => Array
(
...
[car_name] => Car 1
[garage_id] => 1
...
解决方案
It looks like you are not relating objects correctly. Let's break that down:
If a Garage
Has Many Car
then a Car
Belongs To Garage
, Lets proceed with this idea in mind.
Garage
Has ManyCar
Car
Has ManySecurity
Security
Belongs ToCar
Garage
Has ManySecurity
ThroughCar
In Eloquent you can just go ahead and clap those relations in, it should work given the schema you posted above.
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');
}
}
And that should be it.
EDIT: You can access all these relations from any model as long as there is a path you can draw from one model to another using a combination of these relations. Check this out for example:
$security = Security::with('car.garage')->first();
will retrieve first Security
record and load Car
relation on it, then it goes one more step and load all Garage
relations on every Car
object loaded under Security
model.
You can access them using this syntax:
$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";
}
}
Furthermore, notice that the relationship objects are an instance of Collection
so you have all the fancy methods such as ->each()
, ->count()
, ->map()
available on them.
相关文章