使用Laravel 4.1进行hasManyThrough的加载

时间:2014-05-07 05:05:30

标签: laravel-4

我有以下表结构;

users
user_id | email             | name
==================================
1       | tom@example.org   | Tom
2       | pete@example.org  | Pete

trainings
training_id | user_id   | title
=================================================
1           | 1         | First training of Tom
2           | 1         | Second training of Tom
3           | 2         | First training of Pete
4           | 2         | Second training of Pete

calendar
calendar_id | training_id   | when_date
=================================================
1           | 1             | 2014-08-01 10:00:00
2           | 1             | 2014-08-08 10:00:00
3           | 1             | 2014-08-15 10:00:00
4           | 2             | 2014-08-01 18:00:00
5           | 2             | 2014-08-03 18:00:00
6           | 2             | 2014-08-05 18:00:00
7           | 3             | 2014-08-12 16:30:00
8           | 4             | 2014-08-09 22:30:00

我为这个表结构准备了三个模型

class User extends Eloquent
{
    public function trainings()
    {
        return $this->hasMany('Training');
    }

    public function events()
    {
        return $this->hasManyThrough('Calendar', 'Training', 'user_id', 'training_id');
    }
}

class Training extends Eloquent
{
    public function user()
    {
        return $this->belongsTo('User');
    }

    public function events()
    {
        return $this->hasMany('Calendar');
    }
}

class Calendar extends Eloquent {

    public function training()
    {
        return $this->belongsTo('Training');
    }

}

我希望为所选用户(user_id = 1)获取最近事件排序的最新N个日历事件,其中包含此日历事件的所有培训详情。当我执行以下操作时,急切的加载似乎无法正常工作。

$events = User::with('events', 'trainings')->find($userId);

foreach ($events as $event) {
    echo $event->training->title; // runs a separate query to get the title of the training
}

如果给定用户有100多个事件,则会运行100多个查询。

如何通过急切加载来实现这一目标?

2 个答案:

答案 0 :(得分:0)

你不应该首先获取用户,然后通过该实例进行查询吗?

$user = User::find(userId);
$events = $user->with('events', 'trainings');

或一气呵成:

User::find(userId)->with('events', 'trainings');

答案 1 :(得分:0)

你可以通过使用懒惰的预先加载来实现这一点。在你的情况下:

$user = User::with('events')->find($userId);
$user->events->load('training');

foreach ($user->events as $event) {
    echo $event->training->title;
}