理解雄辩的一对多关系

Posted

技术标签:

【中文标题】理解雄辩的一对多关系【英文标题】:Understanding Eloquent One-to-many Relationships 【发布时间】:2020-09-20 06:27:12 【问题描述】:

我试图理解 Eloquent 关系,但似乎我在理解它时遗漏了一些东西。我有:

一个Meeting 产生许多Documents。 可以为一个Meeting 生成一个特定的Document

因此是一对多的关系。我正在尝试在Document 详细信息表中显示 'meeting_name',但出现此错误:

试图获取非对象的属性“meeting_name”(查看:C:\wamp64\www\yajra_contact_system\resources\views\documents\index.blade.php

这是我的代码。

请用代码解决方案说明:

app\Document.php 文件:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Document extends Model

    protected $fillable = [
        'document_name',
        'document_desc',
    ];

    public function meeting()
        return $this->belongsTo(Meeting::class);
    

app\Meeting.php 文件:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Meeting extends Model

    protected $fillable = [
        'document_id',
        'meeting_name',
        'meeting_desc',
        'room_no',
        'no_of_invitees',
        'comments'
    ];

    public function documents()
        return $this->hasMany(Document::class);
    

app\Http\Controllers\DocumentsController.php 文件:

namespace App\Http\Controllers;

use App\Document;
use App\Meeting;
use Illuminate\Http\Request;

class DocumentsController extends Controller

    public function index()
    
        $documents =  Document::all();
        $meetings = Meeting::all();        

        return view('documents.index', compact('documents', 'meetings'));
    

resources\views\documents\index.blade.php 文件:

@foreach($documents as $document)
    <tr>
        <td>$document->id</td>
        <td>$document->document_name</td>
        <td>$document->document_desc</td>
        <td>$document->meetings->meeting_name</td> <!-- ERROR IS HERE -->
    </tr>
@endforeach

【问题讨论】:

你可以在 dd($document->meetings); 时发布结果吗?很可能你得到了一个数组。试试 $document->meetings->first()->meeting_name 当我尝试 $document->meetings->first()->meeting_name 时:Facade\Ignition\Exceptions\ViewException Call to a member function first() on null (View: documents\index.blade.php 我不太清楚如何在控制器中使用 dd()。对 Laravel 有点陌生 这意味着你试图获得的关系是空的。只需在 @foreach 之后在视图中输入此内容, dd($document->meetings) 然后刷新浏览器 我死后的值是 null 并转储到 @foreach, dd($document->meetings) 【参考方案1】:

所以你把你的桌子弄混了。

您每次会议都有一个记录,但您的会议表中有一个 document_id,您需要为每个文档复制会议记录。

从会议表中删除 document_id

将 meeting_id 添加到您的文档表中

记得更新您的模型错误数组,否则您将无法获得集合中的新列。

这应该可以解决您的问题,因为您的关系是正确的。

【讨论】:

非常感谢 Jelly Bean,我认为您的反馈表明我的数据库结构存在更多问题。我的原始代码在我听取了您对 db 结构(即交换 FK)的建议后才起作用。交换 FK 后,我还更改了 belongsTohasMany 函数的位置。所以我很好。仅供参考,该视频对这种特定情况也最有帮助youtube.com/watch?v=3Oxfi3DLdkI【参考方案2】:

你的代码有很多问题:

首先:为了使用关系...你必须先加载它...

使用 with('relationName') 方法加载关系...

在索引中:

$documents =  Document::with('meeting')->all();

秒:

 <td>$document->meetings->meeting_name</td> <!-- ERROR IS HERE -->

关系被命名为没有s的会议..不是会议...

第三个:

提供相关外键是有害的做法:

在会议模式中

  public function documents()
        return $this->hasMany(Document::class,'meeting_id');
    

在文档模型中:

 public function meeting()
        return $this->belongsTo(Meeting::class,'meeting_id');
    

请确保您的文档表中有一个名为 meeting_id 的列,作为会议表中 id 的外键引用

关于加载关系的更多细节:

https://laravel.com/docs/7.x/eloquent-relationships#eager-loading

【讨论】:

以上是关于理解雄辩的一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

laravel 雄辩的关系一对多返回 null

Laravel 5.4雄辩的一对多关系

雄辩的一对多关系在生产服务器上不起作用

Laravel 5.6 |雄辩的一对多关系

在没有主键但在多个重叠字段上加载模型一对多关系的雄辩方式

雄辩的,每个表的多个关系