如何在 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
实例。相当于把关系调用为方法,然后在末尾附加->get()
,所以这两者是等价的:
$bulletin->deals()->get()
// equals to:
$bulletin->deals
检查this other answer,它回答了你的问题。
【讨论】:
SQLSTATE[42000]:语法错误或访问冲突:1103 表名不正确'deals_items'(SQL:选择own
.*,deals_items
.deal_id
为pivot_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 中创建所有三个文件(控制器、模型和数据库迁移文件)