有一个通过 Laravel Eloquent

2021-12-26 00:00:00 php laravel laravel-5 laravel-4 eloquent

我有三个表garagescarssecurities.

证券是保护一辆汽车的安全,您可以拥有多个安全,但一个安全只能保护一辆车.车库是汽车所在,证券也是.

我想要的是列出所有证券并知道他所在的车库的名称.问题是 securities 没有包含车库 id 的列,只有他保持安全的汽车的 id,但是 car 有车库的 id.

Laravel Eloquent 有一个名为 hasManyThrough 的方法,但 securities 只有一个 garagecars.>

这是表格:

车库表:

-----------------------------------|车库编号|车库名称|车库大小|---------------------|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 Many Car
  • Car Has Many Security
  • Security Belongs To Car
  • Garage Has Many Security Through Car

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.

相关文章