在 Laravel 6 中从外键获取数据

Posted

技术标签:

【中文标题】在 Laravel 6 中从外键获取数据【英文标题】:Getting data from foreign key on view in Laravel 6 【发布时间】:2020-04-19 14:31:43 【问题描述】:

我想做的是从表中获取一行,使用其中的外键链接到另一个表,然后在视图中显示该行的特定列。

在某些情况下,这是一个关于体育赛事的网站。在视图内部,用户应该能够看到单击事件的详细信息。在这些细节中应该是运动类别和运动。但是,我在 Laravel 6.5 中找不到这样做的方法。


我有什么:

数据库表:

sport_categories (id, name)
sports (id, sport_category_id, name)
events (id, title, sport_category_id, sport_id)

事件控制器

public function show(Event $event) 

    return view('events.show', ['event' => $event]);

查看

<div id="event-sport-category">
   <span>Sport Category:</span>
   <span id="show-event-sport-category-label">$event->sport_category_id</span>
</div>
<div id="event-sport">
   <span>Sport:</span>
   <span id="show-event-sport-label">$event->sport_id</span>
</div>

SportCategory 模型(空)

class SportCategory extends Model

    //

运动模特

class Sport extends Model

    public function user()
    
        return $this->belongsTo(User::class);
    

事件模型

class Event extends Model

    public function user()
    
        return $this->belongsTo(User::class);
    

当然此时返回给视图的只是events 表的id 列。如何返回每个id对应的name

【问题讨论】:

【参考方案1】:

根据您的数据库设置:

sport_categories (id, name) 体育(id、sport_category_id、名称) 事件(id、title、sport_category_id、sport_id)

所以.. 在这个回复中,我假设:

一个Category有很多Sports 一个Sport有很多Events

注意:鉴于Sport 已经属于Category,您不需要在events 表中指定category_sport_id 键:相关的@ 987654332@ 行应该已经有了。

现在,回答你的问题..

如何返回每个id对应的名字?

定义Relationships。

在您的Category.php 模型中:

class SportCategory extends Model


    protected $guarded = []; // <---

    // ...

    public function sports() // <---
    
        return $this->hasMany(Sport::class);
    

您的Sport.php 型号:

class Sport extends Model


    protected $guarded = []; // <---

    // ...

    public function events() // <---
    
        return $this->hasMany(Event::class);
    

    public function category() // <---
    
        return $this->belongsTo(SportCategory::class);
    

在您的Event.php 模型中:

class Event extends Model


    protected $guarded = []; // <---

    // ...

    public function sport() // <---
    
        return $this->belongsTo(Sport::class);
    

注意:我在每个模型中添加了protected $guarded = [];,这是告诉 Laravel 在返回视图时包含所有字段。 Read this.

现在您的关系已定义,您需要在将变量返回到视图之前加载关系。当然,您可以在视图本身中加载关系,但要优化您的查询,您 should eager 会像这样加载此对象(在这种情况下,延迟急切加载,因为您已经使用模型绑定解析对象):

public function show(Event $event) 

    $event->load('sport.category'); // <---

    return view('events.show', ['event' => $event]);

现在你应该在你的 $event 变量中有这些记录:$event-&gt;sport 和嵌套的$event-&gt;sport-&gt;category 所以为了在你的视图中输出它们:

<p>   $event->sport->name  </p>
<!-- ... -->
<p>  $event->sport->category->name  </p>

【讨论】:

好的,我按照你在模型和控制器中所说的做了,但是视图提出了一个错误。 &lt;p&gt; $event-&gt;sport-&gt;name &lt;/p&gt; 部分工作正常,但 &lt;p&gt; $event-&gt;sport-&gt;category-&gt;name &lt;/p&gt; 部分给出错误消息:“尝试获取非对象的属性'名称'”。 @BillM。检查Sport 模型上的category() 关系。似乎没有加载嵌套关系。 好吧,我尝试从控制器的 $event 中删除“运动”,($event-&gt;load('category');)并返回此错误:“调用模型 [App\Event] 上的未定义关系 [类别] .".所以我决定将sportCategory 函数添加到事件模型(public function category() return $this-&gt;belongsTo(SportCategory::class); )中,该函数适用于第一个视图

而不是第二个视图,因为它给出了相同的错误“尝试获取属性'名称'非对象”。如果此时我将控制器事件更改为 sport.category,同样的错误。

@BillM。当您删除“运动”时。作为关系的一部分,您试图在没有运动的情况下访问类别关系..鉴于我的设置,这是不可能的。这就是为什么很重要。与您的第二次尝试相关:是的,您可以在那里定义关系,但您不需要这样做,因为它可以通过 Sport 模型访问。也许是钥匙的问题。我将更新我的答案以明确提及主键/外键。 好的,我已经在 SportCategorySport 模型中添加了这些键。看看@BillM。

以上是关于在 Laravel 6 中从外键获取数据的主要内容,如果未能解决你的问题,请参考以下文章

Django从外键获取数据

在 laravel 中将数据从外键添加到数据库中

使用NHibernate从外键获取MySQL表中的数据

在 Django 中从外键设置会话变量:需要字段名而不是主键

Laravel:当我的外键在数组中时,如何在模型中添加关系?

如何通过外键获取数据?