laravel - hasOneThrough 与数据透视表 laravel 雄辩
问题描述
我有以下表格
mysql> describe records;
+-----------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| event_school_id | bigint(20) unsigned | NO | MUL | NULL | |
| athlete_id | bigint(20) unsigned | NO | MUL | NULL | |
| year | int(10) unsigned | NO | | NULL | |
| place | int(10) unsigned | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| deleted_at | timestamp | YES | | NULL | |
+-----------------+---------------------+------+-----+---------+----------------+
8 rows in set (0.01 sec)
mysql> describe event_school;
+------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| event_id | bigint(20) unsigned | NO | MUL | NULL | |
| school_id | bigint(20) unsigned | NO | MUL | NULL | |
| notes | text | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| deleted_at | timestamp | YES | | NULL | |
+------------+---------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
mysql> describe events;
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(191) | NO | | NULL | |
| category_id | bigint(20) unsigned | NO | MUL | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| deleted_at | timestamp | YES | | NULL | |
+-------------+---------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
从我的 Record Eloquent 模型中,我如何从记录中获取事件。它需要通过 event_school 数据透视表;但我没有 EventSchool 的模型。我需要做一个吗?如果没有 EventSchool 模型,有没有办法做到这一点?
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class EventSchool extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
protected $table = 'event_school';
public function event()
{
return $this->belongsTo('App\Event');
}
public function school()
{
return $this->belongsTo('App\School');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Record extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
public function athlete()
{
return $this->belongsTo('App\Athlete');
}
function event_school()
{
return $this->belongsTo('App\EventSchool','event_school_id');
}
function event()
{
//What can I put here to complete method
//right now have to do \App\Record::find(1)->event_school->event
//Want to do \App\Record::find(1)->event
}
}
编辑:
这是答案之一的输出
>>> \App\Record::find(3)->event_school->event
=> App\Event {#3035
id: 1,
name: "100 Meter",
category_id: 1,
created_at: null,
updated_at: null,
deleted_at: null,
}
>>> \App\Record::find(3)->event
=> null
解决方案
每次我遇到这种情况时,我最终都会为数据透视表创建一个模型。这样做的另一个好处是,您可以直接访问该表,而无需带入关系的另一端。
您已经拥有外键 ( notes
) 的附加信息。如果您有 aSchool
并且需要notes
from an Event
,但不需要Event
,则如果数据透视表有模型,则可以这样做。
当然,您可以join
在不需要模型的情况下使用 a 来完成。
这里的关键是扩展 fromPivot
而不是Model
. 它所做的一件事是将表名设为单数。但是你不能使用SoftDeletes
(你真的需要它吗?它没有多大意义)
注意:Pivot 模型可能不使用 SoftDeletes 特征。如果您需要软删除数据透视记录,请考虑将数据透视模型转换为实际的 Eloquent 模型。
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class EventSchool extends Pivot
{
protected $guarded = ['id'];
public function event()
{
return $this->belongsTo(Event::class);
}
public function school()
{
return $this->belongsTo(School::class);
}
}
现在,hasOneThrough与您需要的相反。你需要类似的东西belongsToThrough
,但它不存在。您可以使用的是访问器:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Record extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
public function athlete()
{
return $this->belongsTo(Athlete::class);
}
function eventSchool()
{
return $this->belongsTo(EventSchool::class);
}
function getEventAttribute()
{
return $this->eventSchool->event;
}
}
做\App\Record::find(1)->event
会做你期望它做的事情。
推荐阅读
- angularjs - AngularJS:在具有自己的 $scope 的模式内使用 Ctrl $scope
- javascript - 了解 for 循环中的闭包?
- vue.js - TypeError: this.$route.push is not a function vue.js and Uncaught TypeError: Cannot read property 'push' of undefined
- android - Android SearchView 禁用/隐藏 QuickSearchBox/Suggestion
- fonts - 游戏制作者 1.2 中的字体问题
- crm - 关于匿名用户的 Azure B2C AD
- node.js - POST 400(错误请求)位置 1 的 JSON 中的意外标记 o
- libgdx - 如何从 LibGdx 中的高度图创建地形网格
- ios - 在ios uiwebview Objective-c中检查布尔值是yes还是no时出错
- r - 在 ggplot 的循环中为 geom_contour 使用 direct.labels