簡體   English   中英

Laravel Eloquent查詢意外結果

[英]Laravel Eloquent query unexpected result

我發現一些查詢結果真的出乎意料。

這是Laravel 5.2

我們有以下實體:

User方法:

public function roles() : BelongsToMany
{
    return $this->belongsToMany(Role::class)->withPivot('timestamp');
}

每個User都可以擁有多個角色,因此我們還有Role實體(但在我的問題中並不重要)和帶有timestamp字段的pivotuser_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包含它! 所有其他Usersroles字段都包含空數組

為什么單獨對每個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM