我有下表
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
答案 0 :(得分:1)
我在计算机上全新安装了laravel,并根据您提供的信息建立了模型和关系,而我想到的最简单的解决方案是:
public function event()
{
return $this->hasOneThrough(Event::class, EventSchool::class,
'event_id', 'id', 'id', 'event_id'
);
}
这是我所做的测试:
// Within some controller:
$record = Record::find(2);
dd($record->event);
这是结果,我认为这是您要寻找的结果:
Event {#303 ▼
#connection: "pgsql"
#table: "events"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▼
"id" => 2
"name" => "Event 2"
"category_id" => 2
"created_at" => "2019-09-16 03:15:07"
"updated_at" => "2019-09-16 03:15:07"
"laravel_through_key" => 2
]
#original: array:6 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
希望有帮助。
答案 1 :(得分:1)
每次遇到这种情况时,我都会为数据透视表创建一个模型。这样做的另一个好处是,您可以直接访问该表,而不必牵扯到关系的另一端。
您已经有了有关外键(notes
)的其他信息。如果您有School
,并且需要notes
中的Event
,但是您不需要Event
,则只要数据透视表具有模型,就可以这样做。
当然,您可以使用join
来完成此操作,而无需模型。
此处的关键是从Pivot
而不是Model
扩展。它要做的一件事是使表名成为单数。但是您不能使用SoftDeletes
(您真的需要吗?这没有多大意义)
注意:数据透视图模型可能不使用SoftDeletes特性。如果您需要软删除透视记录,请考虑将透视模型转换为实际的Eloquent模型。
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class EventSchool extends Model
{
protected $guarded = ['id'];
public function event()
{
return $this->belongsTo(Event::class);
}
public function school()
{
return $this->belongsTo(School::class);
}
}
现在,hasOneThrough可以满足您的需求。您需要类似belongsToThrough
的东西,但是它不存在。您可以使用的是accessor:
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
会完全按照您的期望去做。