記如何在預載入中指定查詢的欄位

韓槑槑發表於2018-04-24

記錄下今天在進行關聯查詢的預載入中一直無法指定需要查詢的欄位原由。
這裡使用的程式碼為 LaraBBs
首先我們先查詢所有使用者以及對應使用者的所有話題。

$result = User::with('topics')
    ->get()
    ->toArray();
dd($result);

得到如下結果。
file
然後我們來查詢第一名使用者,也就是 Summer 同學的資訊及其所有話題。

$result = User::with('topics')
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

得到如下結果。
file
此時我們如果只想看話題的 內容標題
根據 文件 中介紹。
file

$result = User::with('topics:body,title')
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

得到如下結果。
file
emmmmm,我的話題內容呢?
仔細看上方文件截圖最後一句發現 使用這個方法時,在你想獲取的列中應始終有 id 列。
哦,原來始終需要加上 id 列,讓我們再來一次。

$result = User::with('topics:id,body,title')
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

得到如下結果。
file
emmmmm,為什麼還是木有啊。
再讓我們通過 debugbar 檢視進行了怎樣的 sql 語句。
file
sql 語句放入資料庫檢視管理工具中執行。
file
沒毛病啊,能查出來啊。
好吧,讓我們仔細分析一下 sql 語句。
所謂的預載入先是通過 select * from 'users' where 'name' = 'Summer' 查出所有使用者的資訊。
然後通過關聯屬性將所查出的所有使用者 id 取出帶入第二個 sql 語句中
select 'id', 'body', 'title' from 'topics' where 'topics'.'user_id' in ('1')
最後要生成我們平時所看到的資料結構應該是將兩次查詢的結果按照按照兩張表的關聯進行合併。
在這次的查詢中,兩張表的唯一關聯應該是 users.idtopics.user_id 兩欄位。
所以,雖然我們能通過最後一條 sql 語句查出資料,但是資料中並不包含關聯欄位 topics.user_id ,則無法產生關聯,也就無法進行資料合併。
再通過一開始說的那句話 使用這個方法時,在你想獲取的列中應始終有 id 列。 可知,這裡的 id 列應該是關聯欄位列 user_id
知道原因後再讓我們試一下。

$result = User::with('topics:user_id,body,title')
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

得到如下結果。
file
哦耶,Summer 同學的話題又回來了不是。
ps:
如果要進行約束預載入,應該這樣寫。

$result = User::with(['topics' => function ($query) {
    $query->select('id', 'user_id', 'body', 'title')
        ->orderBy('updated_at', 'desc');
    }])
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

file

相關文章