首页 > 解决方案 > 如何在 laravel 中创建 3 个模型之间的关系?

问题描述

SQL方案:

公告

  id increment

交易

  id increment
  seller_id
  buyer_id

deal_items - 项目 = 公告

  id increment
  title
  desc
  bulletin_id
  deal_id

如何通过公告 ID 获取交易行?在原始 SQL 中,它看起来像:

select `deals`.* from `deals` inner join `deals_items` on `deals_items`.`deal_id` = `deals`.`id` where `deals_items`.`bulletin_id` = 10572

我试过了:

public function deals()
{
    return $this->hasManyThrough(DealItem::class,Deal::class, 'bulletin_id','dealid','id');
}

但这似乎是一种错误的方式。在 laravel 文档中找不到关于关系的正确方法。

@HCK 显示正确。

但是当我在刀片模板中执行 $bulletin->deals() 时,我得到了空的交易集合。

当只是 $bulletin->deal - 一切都很好时,我们收集了一些交易。

我在公告模型中使用受保护的 $with = ['deals'],但调用方法或属性有什么不同?为什么方法为空结果?

标签: phplaraveleloquentforeign-keys

解决方案


@Amarnasan 很接近,但外键的顺序是错误的。尝试这个:

交易.php

public function bulletins()
{
    return $this
        ->belongsToMany(Bulletin::class, 'deals_items', 'deal_id', 'bulletin_id')
        ->withPivot('title','desc');
}

公告.php

public function deals()
{
    return $this
        ->belongsToMany(Deal::class, 'deals_items', 'bulletin_id', 'deal_id')
        ->withPivot('title','desc');
}

文档

如前所述,为了确定关系连接表的表名,Eloquent 会按字母顺序连接两个相关模型名。但是,您可以随意覆盖此约定。您可以通过将第二个参数传递给该 belongsToMany方法来做到这一点:

return $this->belongsToMany('App\Role', 'role_user');

除了自定义连接表的名称外,您还可以通过向belongsToMany方法传递附加参数来自定义表上键的列名。第三个参数是要定义关系的模型的外键名称,而第四个参数是要加入的模型的外键名称:

return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');

更新

当您将关系作为方法$bulletin->deals()访问时:您正在访问关系本身。这将返回\Illuminate\Database\Eloquent\Relations\BelongsToMany(在您的情况下)的一个实例。此处查询尚未执行,因此您可以继续为查询添加约束,例如:

$bulletin
    ->deals()
    ->where('seller_id', 45) // <---
    ->skip(5) // <---
    -> ... (And so on)

当您将其作为动态属性访问时,您已经在执行查询,因此这将返回一个Collection实例。和把关系作为方法调用然后->get()在最后附加上是一样的,所以这两者是等价的:

$bulletin->deals()->get()
// equals to:
$bulletin->deals

检查this other answer,它回答了你的问题。


推荐阅读