[英]Laravel Eloquent query unexpected result
我發現一些查詢結果真的出乎意料。
這是Laravel 5.2
我們有以下實體:
User
方法:
public function roles() : BelongsToMany
{
return $this->belongsToMany(Role::class)->withPivot('timestamp');
}
每個User
都可以擁有多個角色,因此我們還有Role
實體(但在我的問題中並不重要)和帶有timestamp
字段的pivot
表user_role
(當然還有ID),因為我們保存有關時間的信息,當User
達到特定時角色。
我想讓所有Users
最后分配Role
當我創建查詢時(在某些存儲庫的User
上下文中):
$this->with(['roles' => function($query) {
$query->orderBy('timestamp', 'desc');
}])->all();
結果將包含按時間戳排序的具有Roles
實體的Users
- 沒關系。 但我想只檢索每個User
實體中的最后一個角色,而不是全部訂購。
所以...
$this->with(['roles' => function($query) {
$query->orderBy('timestamp', 'desc')->limit(1);
}])->all();
然后我檢索Users
但只有最后一次獲得某些Role
User
包含它! 所有其他Users
的roles
字段都包含空數組 。
為什么單獨對每個Users
關系執行排序,但是當我添加limit
它表現得像所有的全局限制。
它讓我瘋狂...
謝謝你的建議。
我已經創建了lastRoles()
方法來獲取所有Roles
命令desc。 但是所有人 ,檢索一個是不可能的。
public function lastRoles() : BelongsToMany
{
return $this->BelongsToMany(Roles::class)->withPivot('timestamp')->latest('timestamp');
}
並進行測試:
$users = (new User())->with('lastRoles')->get();
但是現在我必須迭代Users
並在每個上調用lastRoles()
:
foreach ($users as $user) {
var_dump($user->lastRoles()->get()->first()->name);
}
然后,我檢索分配給每個User
的最新Roles
名稱。
那么......在一個查詢中無法做到這一點 ? 這是唯一的方法嗎?
當您急切地加載與查詢約束的關系時,查詢將運行一次以加載所有關系,而不是單獨加載每個關系。 這是預期的行為。 考慮一下,存在急切加載以將許多查詢轉換為一個查詢以優化性能。 只執行了一個查詢,因此limit
約束將限制整個結果集,而不是基於每個模型。
為了避免這種情況,您可以嘗試創建另一個添加所需限制約束的belongsToMany
方法。 以下代碼未經測試:
public function lastRole() : BelongstoMany
{
return $this->belongsToMany(Role::class)
->withPivot('timestamp')
->orderBy('timestamp', 'desc')
->limit(1);
}
假設這有效,您可以簡單地將關系方法從roles
更改為lastRole
並刪除查詢約束:
$this->with('lastRole')->all();
為此,您需要一個輔助函數:
public function latestRole()
{
return $this->hasOne(Role::class)->withPivot('timestamp')->orderBy('timestamp', 'DESC');
}
接着:
$this->with('latestRole')->get();
這篇精彩文章的功勞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.