繁体   English   中英

Laravel雄辩的ORM与查询生成器

[英]Laravel's Eloquent ORM versus Query Builder

我有2个表格: usersarticles users表有一个名为is_suspended的列,它接受yesnoarticles表有一个名为is_published的列,它接受01 为了从数据库中获取的文章数据, articles.is_published必须等于1users.is_suspended必须等于no 现在假设users.is_suspended等于yes ,如果我尝试使用Query Builder来获取文章数据,如下所示:

// first code:

    $articles = Article::join('users', 'articles.user_id', '=', 'users.user_id')
        ->select(['articles.*', 'users.user_name', 'users.user_email'])
        ->where('articles.article_id', '=', 9)
        ->where('articles.is_published', '=', 1)
        ->where('users.is_suspended', '=', 'no')
        ->get();

这将完美运行,并且不会返回任何内容(因为users.is_suspended = yes )。 现在,让我们尝试使用Laravel Eloquent ORM来获取同一篇文章,如下所示:

// second code:

$articles = Article::with([
    'user' => function($query) {
        $query->select(['user_id', 'user_name', 'user_email'])
            ->where('users.is_suspended', '=', 'no');
    }])
    ->where('articles.article_id', '=', 9)
    ->where('articles.is_published', '=', 1)
    ->get();

在这种情况下,我将得到下一个结果:

[
  {
    article_id: 9,
    user_id: 1,
    article_title: "Article title here",
    article_body: "Article body here",
    is_published: 1,
    created_at: "2015-01-17 02:26:24",
    updated_at: "2015-01-17 02:26:24",
    user: null
  }
]

即使用户被暂停,它也会获取文章的数据,这是错误的。 所以我的问题是如何将第二个代码修复为像第一个代码一样?

您可能需要使用with来确保您的延迟加载关系是延迟的,但是对它施加的任何约束都仅适用于加载的关系。 为了将响应限制为不暂停用户的文章,您需要使用whereHas方法。

$articles = Article::with(['user' => function($q){
        $q->select(['user_id', 'user_name', 'user_email', 'created_at']);
    }])
    ->whereHas('user', function($q) {
        $q->where('is_suspended', '=', 'no');
    })
    ->where('articles.article_id', '=', 9)
    ->where('articles.is_published', '=', 1)
    ->get();

你需要whereHas ,而不是with (或两者兼而有之,但没有必要with在这种情况下),像@DavidBarker说。

但是我建议更多,考虑一下此代码的可读性:

$article = Article::whereHas('user', function ($q) {
   $q->active();
})->published()->find(9);

它利用范围

因此,您可以采取以下措施使自己的生活更轻松:

  1. is_suspended更改为bool因为:

     $user->is_suspended; // no (bool) $user->is_suspended; // true 
  2. 定义在User模型上suspended并在Articlepublished范围:

     // Article model - on User accordingly public function scopePublished($query) { $query->where('is_published', 1); } 
  3. 当您要获取单个模型时,请使用find($id)where('col', $id)->first()代替get ,因为即使有一个突出的结果,后者也会返回一个集合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM