Laravel 当事人关系

Laravel Parties relationship

大家早上好, 我真的对 Laravel 的实体关系问题失去了理智。 我使用的是 Laravel、8.x 的最新版本。 我的数据模型组成如下。

派对Table

  1. id
  2. party_details_id
  3. party_type

人Table

  1. id
  2. party_type ('P')
  3. 姓名
  4. 姓氏

公司Table

  1. id
  2. party_type ('C')
  3. 姓名
  4. 姓氏

正如您从示例中看到的,“派对”是 table 包含所有派对,包括个人和公司。连接密钥是双重的,即由“party_details_id”和“party_type”组成的对。 在“Parties”table中,“party_details_id”一栏可以有两个相等的值但是“party_details_id”和“party_type”只能有一个值”。 我很难在 Laravel 上建立关系。看了几篇文章我遇到了这种情况:

派对模型

public function companies()
    {
        return $this->hasMany(Companies::class, 'id', 'party_details_id')->where('party_type', 'C');
    }

    public function people()
    {
        return $this->hasOne(People::class, 'id', 'party_details_id')->where('party_type', 'P');
    }

人物模型

public function party()
    {
        return $this->belongsTo(Parties::class, 'party_details_id')->where('party_type', 'P');
    }

公司模型

public function party()
    {
        return $this->belongsTo(Parties::class, 'party_details_id', 'id')->where('party_type', 'C');
    }

在测试路线中我插入了这段代码:

Route::get('/people', function () {
    $people = new People();
    return $people->with('party')->get()->toArray();
});

我得到的是:

[
  {
    "id": 1,
    "party_type": "P",
    "name": "Alex",
    "surname": "test",
    "created_at": "2021-09-20T20:14:07.000000Z",
    "updated_at": null,
    "party": null
  }
]

从回答中可以看出,“聚会”是空的。 为什么?从 Telescope 查看启动的查询,我看到了这个:

select * from `parties` where `party_type` = 'P' and 0 = 1

我做错了什么?你能帮我处理这段关系吗? 谢谢

我相信你的意思是党可以属于人民模式或公司模式,而不是两者。如果这是真的,那么使用多态的一对多关系。

Laravel 文档: https://laravel.com/docs/8.x/eloquent-relationships#one-to-many-polymorphic-relations

公司

注意:受保护的 $with 属性确保派对始终加载对象。

class Company extends Model
{
    protected $with = ['party'];

    public function party()
    {
        return $this->morphMany(Party::class,'object');
    }
}

人物模型

注意:受保护的 $with 属性确保派对始终加载对象。

class People extends Model
{
    protected $with = ['party'];

    public function party()
    {
        return $this->morphMany(Party::class,'object');
    }
}

派对模特

然后您将在 Party 模型上有一个 'object' 关系,这样 $party->object 要么是 People 要么是 Company。我建议使用 'object' 关系而不是 'people' 和 'company' 关系,因为所有模型都会有其中之一,但我将两者都包括在此处以防您需要。

class Party extends Model
{
    public function object()
    {
        return $this->morphTo();
    }

    public function people()
    {
        return $this->belongsTo(People::class,'object_id')->where('object_type','=',People::class);
    }

    public function company()
    {
        return $this->belongsTo(Company::class,'object_id')->where('object_type','=',Company::class);
    }
}

现在你可以使用$party->object,或者$party->people和$party->company来获取它所属的Person或Company。

$party->object; // Either Company or People object
$party->people; // People object, would fail if the party belongs to Company
$party->company; // Company object, would fail if the party belongs to People 

现在,当您获取 People 或 Company 对象时,它应该会自动包含 Party。

Route::get('/people', function () {
    $people = new People();
    return $people->get()->toArray();
});

如上所述,$with 属性可确保每次自动加载聚会。如果您不想每次都加载派对,请删除 $with 属性并在之后加载它。

Route::get('/people', function () {
    $people = new People();
    return $people->with('party')->get()->toArray();
});