简体   繁体   English

如何反转 Eloquent has one and has many through (laravel 5.8)?

[英]How to Inverse the Eloquent Has One and Has Many Through (laravel 5.8)?

I have three relational table attached below.我在下面附上了三个关系表。

https://drive.google.com/file/d/1q1kdURIwFXxHb2MgdRyBkE1e3DMug7r-/view?usp=sharing https://drive.google.com/file/d/1q1kdURIwFXxHb2MgdRyBkE1e3DMug7r-/view?usp=sharing

I have also three separate models where defined relation among all of my table's.I can read the City Model's information from Country model using hasManyThrough() relation But cannot read the Country information from City model.我还有三个单独的模型,其中定义了所有表之间的关系。我可以使用hasManyThrough()关系从 Country 模型中读取 City 模型的信息,但无法从 City 模型中读取 Country 信息。 I have tried to retrieve City model's using ``hasManyThrough``` but didn't get result (attached as commented country method ).我尝试使用“hasManyThrough”检索城市模型,但没有得到结果(附加为评论国家方法)。 Please read my model and it's relational method here..请阅读我的模型和它的关系方法在这里..

Is there someone to help me for getting City model's information using Eloquent method hasManyThrough / hasManyThrough or using inverse of hasManyThrough / hasManyThrough ?有没有人可以帮助我使用 Eloquent 方法hasManyThrough / hasManyThrough或使用hasManyThrough / hasManyThrough的逆来获取 City 模型的信息?

01. 01.

<?php

namespace App\Hrm;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Country extends Model
{
    //use SoftDeletes;
    protected $fillable = ['name','description','status'];


    public function districts(){
        return $this->hasMany(District::class);
    }


    public function cities(){
        return $this->hasManyThrough(City::class,District::class);
    }


}

02. 02.

<?php

namespace App\Hrm;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class District extends Model
{
    //use SoftDeletes;
    protected $fillable = ['country_id','name','description','status'];


    public function country(){
        return $this->belongsTo(Country::class);
    }

    public function cities(){
        return $this->hasMany(City::class);
    }

}

3. 3.

namespace App\Hrm;

use App\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class City extends Model
{
    //use SoftDeletes;
    protected $fillable = ['district_id','name','description','status'];

    public function district(){
        return $this->belongsTo(District::class);
    }

//    public function country(){
//        return $this->hasOneThrough(Country::class, District::class);
//    }

Doesn't look like there is a native way to define the inverse of a "hasManyThrough" relationship yet in Laravel.在 Laravel 中似乎还没有一种本地方式来定义“hasManyThrough”关系的逆。 There have been a few issues opened on github to request it, but they were closed.在 github 上打开了一些问题来请求它,但它们被关闭了。

You could use the staudenmeir/belongs-to-through package if you don't mind installing a third-party package for this functionality.如果您不介意为此功能安装第三方软件包,则可以使用staudenmeir/belongs-to-through软件包。 Then you should be able to define a belongsToThrough relationship like this:然后你应该能够像这样定义一个belongsToThrough关系:

class City extends Model
{
    use \Znck\Eloquent\Traits\BelongsToThrough;

    public function country() {
        return $this->belongsToThrough(Country::class, District::class);
    }
}

Why can't use parent method?为什么不能使用父方法?

$city = City::find(1);
$country = $city->district->country();

i just had a similar situation i was able to accomplish a belongsToThrough with hasOneThrough我刚刚遇到了类似的情况,我能够用hasOneThrough完成一个belongsToThrough

public function country()
{
    return $this->hasOneThrough(
        Country::class,       // model we are trying to get
        District::class,      // model we have an _id to
        'id',                 // WHERE `district`.`id` = `city`.`district_id`
        'id',                 // `countries`.`id`
        'district_id',        // local column relation to our through class
        'country_id'          // `district`.`country_id`
    );
}

what this should generate is这应该产生的是

SELECT * FROM `countries` 
    INNER JOIN `districts` 
        ON `districts`.`country_id` = `countries`.`id`
    WHERE `districts`.`id` = ?


-- ? == city.district_id

Database structure:数据库结构:

City:
    id: increments
    district_id: integer
    ...

Country:
    id: increments
    ...

District:
    id: increments
    country_id: integer
    ...

we can then do $city->country然后我们可以做$city->country

note: i have not fully tested this but with the testing that i have done it 'works'注意:我尚未对此进行全面测试,但通过测试我已经完成了它“有效”

Edit: i originally thought that i needed to leave the localKey parameter null otherwise the relation wont work.编辑:我最初认为我需要将 localKey 参数保留为空,否则关系将不起作用。 it turns out i didnt fully understand what that column was doing and that was wrong.事实证明,我没有完全理解该专栏在做什么,这是错误的。 That key is the local column that relates to our through column (unless i still have more to learn/figure out), when left the value as null, it would use the local id column which a.该键是与我们的直通列相关的本地列(除非我还有更多需要学习/弄清楚),当将值保留为空时,它将使用本地 id 列。 is the wrong value, b.是错误的值,b。 can also be out of range (which is how i discovered it was using the wrong value)也可能超出范围(这就是我发现它使用错误值的原因)

in my testing i only had two rows, both with the same relations.在我的测试中,我只有两行,都具有相同的关系。 what i didnt realize though was that on the "through table" both row 1 and 2 and the same related (relation where are trying to reach) so i didnt notice the issue right away.我没有意识到的是,在“通过表”上,第 1 行和第 2 行以及相同的相关(试图达到的关系)所以我没有立即注意到这个问题。 hopefully now its all working希望现在一切正常

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM