簡體   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