![](/img/trans.png)
[英]Laravel 4 Eloquent - Utilize/Access ORM Relationship Properties in Query Builder
[英]Laravel's Eloquent ORM versus Query Builder
我有2個表格: users
和articles
。 users
表有一個名為is_suspended
的列,它接受yes
或no
, articles
表有一個名為is_published
的列,它接受0
或1
。 為了從數據庫中獲取的文章數據, articles.is_published
必須等於1
和users.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);
它利用范圍 。
因此,您可以采取以下措施使自己的生活更輕松:
將is_suspended
更改為bool
因為:
$user->is_suspended; // no (bool) $user->is_suspended; // true
定義在User
模型上suspended
並在Article
上published
范圍:
// Article model - on User accordingly public function scopePublished($query) { $query->where('is_published', 1); }
當您要獲取單個模型時,請使用find($id)
或where('col', $id)->first()
代替get
,因為即使有一個突出的結果,后者也會返回一個集合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.