Laravel - Eager加载非关系方法(N + 1期)

时间:2016-05-14 22:46:34

标签: php multithreading laravel laravel-5.2

随着laravel的热切加载,我可以做类似

的事情

$forums = Forum::with('posts', 'threads')->get();

将线程作为其帖子和论坛,而不需要做很多查询。

但是,我有一个方法可以获得论坛的最后一篇文章。

这是Forum.php

中的方法
public function lastThread()
{
    $forums = $this->arrayOfIDs(); // get array of all ids, even subforum's subforums.
    return Thread::whereIn('forum_id', $forums)->orderBy('updated_at', 'desc')->first();
}

这是我获取最后一个帖子的部分视图:

@if ($subforum->lastThread())

    <a href="{{ viewThread($subforum->lastThread()) }}">
        {{ $subforum->lastThread()->title }}
    </a>
    <br>
    <a href="{{ viewPost($subforum->lastThread()->lastPost) }}"> {{ trans('forum/post.last_post') }}
        :</a>
    <a href="{{ viewProfile($subforum->lastThread()->lastPost->user) }}"> {{ $subforum->lastThread()->lastPost->user->info() }}</a>
    <br>
    {{ $subforum->lastThread()->lastPost->created_at }}

@endif

如你所见,如果我正在做$subforum->lastThread()很多。我可以将它存储在$lastThread = $subforum->lastThread()这样的变量中,然后执行类似$lastThread->created_at之类的操作来减少查询次数,但我认为只要将原始查询包含在内以获取所有论坛就会容易得多。

可能是这样的:$forums = Forum::with('posts', 'threads', 'lastThread')->get();?我试过为这个方法做一个hasOne关系,但这不起作用,因为最后一个线程不一定属于那个特定的子论坛。

无论如何,我怎样才能最好地解决这个N + 1问题?

谢谢。

1 个答案:

答案 0 :(得分:0)

你有无穷无尽的选择,

如果Cache类适合您,那么我将使用此路径,您也可以这样做:

protectd $lastThread;

public function lastThread()
{
     if ($this->lastThread) return $this->lastThread;
     return $this->fetchLastThread();
}

    public function fetchLastThread() {
         $forums = $this->arrayOfIDs(); // get array of all ids, even subforum's subforums.
         $this->lastThread = Thread::whereIn('forum_id', $forums)->orderBy('updated_at', 'desc')->first();
         return  $this->lastThread;
}