在 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
有很多Sport
s
一个Sport
有很多Event
s
注意:鉴于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->sport
和嵌套的$event->sport->category
所以为了在你的视图中输出它们:
<p> $event->sport->name </p>
<!-- ... -->
<p> $event->sport->category->name </p>
【讨论】:
好的,我按照你在模型和控制器中所说的做了,但是视图提出了一个错误。<p> $event->sport->name </p>
部分工作正常,但 <p> $event->sport->category->name </p>
部分给出错误消息:“尝试获取非对象的属性'名称'”。
@BillM。检查Sport
模型上的category()
关系。似乎没有加载嵌套关系。
好吧,我尝试从控制器的 $event 中删除“运动”,($event->load('category');
)并返回此错误:“调用模型 [App\Event] 上的未定义关系 [类别] .".所以我决定将sportCategory
函数添加到事件模型(public function category() return $this->belongsTo(SportCategory::class);
)中,该函数适用于第一个视图 而不是第二个视图,因为它给出了相同的错误“尝试获取属性'名称'非对象”。如果此时我将控制器事件更改为 sport.category,同样的错误。
@BillM。当您删除“运动”时。作为关系的一部分,您试图在没有运动的情况下访问类别关系..鉴于我的设置,这是不可能的。这就是为什么很重要。与您的第二次尝试相关:是的,您可以在那里定义关系,但您不需要这样做,因为它可以通过 Sport 模型访问。也许是钥匙的问题。我将更新我的答案以明确提及主键/外键。 好的,我已经在SportCategory
和 Sport
模型中添加了这些键。看看@BillM。以上是关于在 Laravel 6 中从外键获取数据的主要内容,如果未能解决你的问题,请参考以下文章
在 Django 中从外键设置会话变量:需要字段名而不是主键