【问题标题】:Laravel eloquent "with" the easy wayLaravel 雄辩“用”的简单方法
【发布时间】:2021-03-02 22:46:37
【问题描述】:

我在几个小时前发布了related question,但我不明白为什么 Laravel eloquent 如此复杂......我再次阅读了很多关于这个主题的帖子,但没有人给我一个非常简单的请求的解决方案。

这是一个简单的例子,帖子只属于一篇文章和一个用户。所以关系在 Post 模型中定义如下:

public function article()
{
    return $this->belongsTo(Article::class);
}

public function user()
{
    return $this->belongsTo(User::class);
}

我对 Laravel eloquent 很陌生...所以我只想根据上面模型中定义的关系显示所有帖子的列表,其中包含他们的 id、评论和相关的用户名和文章标题。我相信这很简单,我今天才学会了“with”。

所以在 PostController 中,我有:

$posts = Post::orderBy($sortField,$sortOrder)
    ->with(['article','user'])
    ->get();  

这给了我一个包含所有帖子的集合。

第一个问题,我是否必须以使它们在下面的列表视图中易于访问的方式来操作 2 个相关字段?或者我可以通过将它放在查询中来避免这种情况吗?

foreach ($posts as $post) {
    $post->article = $post->article()->pluck('article');
    $post->user = $post->user()->pluck('name');
}

在上面,字段 $post->article 列出了数组中的所有文章标题(文章字段)。

如果我在末尾添加 [0],我会得到数组的第一个元素。

如果我使用 [post->article_id],我会得到错误的相关标题。

所以没有什么能按我想要的方式工作...为什么这么复杂???

最后,这就是我需要在列表视图中做的事情。

@foreach ($posts as $post)
    <p>{{ $post->id }} : {{ $post->comment }} by {{ $post->name }} from article {{ $post->article }}</p>
@endforeach

通过在查询生成器中进行查询,我立即得到了我想要的......那么如何在 eloquent 中做同样的事情?

$users = DB::table('posts')
    ->join('articles', 'articles.id', '=', 'posts.user_id')
    ->join('users', 'users.id', '=', 'posts.user_id')
    ->select('users.*', 'articles.article', 'users.name')
    ->get();

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    不清楚是什么让你误解了,所以这里解释一下。

    首先,您的帖子模型中有两个belongsTo 关系user 和article。

    当你运行它时

    $posts = Post::orderBy($sortField,$sortOrder)
        ->with(['article','user'])
        ->get();  
    

    你会得到一个帖子集合,文章和用户分别在属性$post-&gt;article 和$post-&gt;user 中。该 queryBuild 将启动 3 个查询,一个用于帖子,一个用于文章,一个用于最终用户。

    现在,在您的刀片中,您想要访问位于 Post 模型内部的 Article 模型中的属性 article,因此您可以这样做:

    @foreach ($posts as $post)
        .... from article {{ $post->article->article }}</p>
    @endforeach
    

    注意:当您调用 $post-&gt;article() 时,您会得到一个查询生成器,因此您可以在其后面加上一个

    • first() => 模型实例 / null
    • get() => 模型实例集合或空集合
    • pluck() => 属性数组
    • value() => 第一个元素的值,就像你使用 pluck 一样
    • ...(还有其他方法可以获得结果)

    当你不带括号调用$post-&gt;article时,它会运行:

    • first() 如果关系是belongsTo
    • get() 如果关系是 belongsToMany 或 HasMany 或....

    或

    如果已获取(集合或模型实例),它将为您提供属性。

    因此,由于您在第一个查询中使用了with('article')(已获取),$post->article 将返回模型 Article 的实例,并且不会运行新的查询。

    【讨论】:

    • 这个非常清楚。我真的不知道我怎么会错过呢?感谢@N69S 抽出时间回复...我会把它放在我的桌子上;)
    猜你喜欢
    • 2017-07-01
    • 2017-03-07
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多