如何在 laravel 中创建 3 个模型之间的关系?

Posted

技术标签:

【中文标题】如何在 laravel 中创建 3 个模型之间的关系?【英文标题】:How to create relationship between 3 models in laravel? 【发布时间】:2019-10-06 20:13:39 【问题描述】:

SQL 方案:

公告

  id increment

交易

  id increment
  seller_id
  buyer_id

deals_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'],但调用方法或属性有什么不同?为什么方法结果为空?

【问题讨论】:

您在哪个模型中创建此关系。并显示数据的响应。 在公告模型中,响应是错误导致 laravel 生成错误查询。我在 hasManyThrough 中使用键并没有成功 - 总是错误的查询。只有在我展示时手动编辑才能按我的意愿工作。 【参考方案1】:

交易类别:

public function bulletins()
    return $this->belongsToMany('App\Bulletin', 'deals_items ', 'bulletin_id', 'deal_id')->withPivot('title','desc');

公告类:

public function deals()
    return $this->belongsToMany('App\Deal', 'deals_items ', 'deal_id', 'bulletin_id')->withPivot('title','desc');

【讨论】:

在这种情况下获得了空的 Deal 集合【参考方案2】:

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

Deal.php

public function bulletins()

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

Bulletin.php

public function deals()

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

来自docs:

如前所述,确定表名 关系的连接表,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 实例。相当于把关系调用为方法,然后在末尾附加-&gt;get(),所以这两者是等价的:

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

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

【讨论】:

SQLSTATE[42000]:语法错误或访问冲突:1103 表名不正确'deals_items'(SQL:选择own.*,deals_items .deal_idpivot_deal_id,@987654340 @.bulletin_id as pivot_bulletin_id, deals_items .title as pivot_title, deals_items .description as pivot_description from own inner join deals_items on @98654350@@986654350@ = deals_items .bulletin_id 其中deals_items .deal_id (3)) - own 是公告表名称 我也不明白为什么我们需要关系交易->公告它在公告->交易中使用关系吗?我认为没有。 @rst630 这不是必需的,定义这两种关系只是一个好习惯,但是你可以跳过它。 @rst630 我的错。我忘了删除它,不过我已经修复了。 现在很好用,但你能解释一下吗 dd($bulletin->deals) - 一切正常,dd($bulletin->deals()) - 在刀片中 - 与交易。我在模型中使用 $with=... 但是当我们调用方法而不是属性时,它只是重新运行查询 - 为什么在这种情况下没有 Deal?【参考方案3】:

交易模式-

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

公告模型:-

public function deals()

    return $this
        ->belongsToMany(Deal::class, 'deals_items',  'deal_id', 'bulletin_id',);

【讨论】:

以上是关于如何在 laravel 中创建 3 个模型之间的关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用单个工匠命令在 Laravel 8 中创建多个模型?

如何使用一个命令在 laravel 中创建所有三个文件(控制器、模型和数据库迁移文件)

在 Laravel 中创建模型时使用受保护的 $table 变量

Laravel 数据库模型自身之间的关系

在 Laravel 中创建排名表

如何在 Laravel 中创建一个 Trait