記錄下今天在進行關聯查詢的預載入中一直無法指定需要查詢的欄位原由。
這裡使用的程式碼為 LaraBBs 。
首先我們先查詢所有使用者以及對應使用者的所有話題。
$result = User::with('topics')
->get()
->toArray();
dd($result);
得到如下結果。
然後我們來查詢第一名使用者,也就是 Summer
同學的資訊及其所有話題。
$result = User::with('topics')
->where('name', 'Summer')
->get()
->toArray();
dd($result);
得到如下結果。
此時我們如果只想看話題的 內容
和 標題
。
根據 文件 中介紹。
$result = User::with('topics:body,title')
->where('name', 'Summer')
->get()
->toArray();
dd($result);
得到如下結果。
emmmmm,我的話題內容呢?
仔細看上方文件截圖最後一句發現 使用這個方法時,在你想獲取的列中應始終有 id 列。
。
哦,原來始終需要加上 id
列,讓我們再來一次。
$result = User::with('topics:id,body,title')
->where('name', 'Summer')
->get()
->toArray();
dd($result);
得到如下結果。
emmmmm,為什麼還是木有啊。
再讓我們通過 debugbar
檢視進行了怎樣的 sql
語句。
將 sql
語句放入資料庫檢視管理工具中執行。
沒毛病啊,能查出來啊。
好吧,讓我們仔細分析一下 sql
語句。
所謂的預載入先是通過 select * from 'users' where 'name' = 'Summer'
查出所有使用者的資訊。
然後通過關聯屬性將所查出的所有使用者 id
取出帶入第二個 sql
語句中select 'id', 'body', 'title' from 'topics' where 'topics'.'user_id' in ('1')
最後要生成我們平時所看到的資料結構應該是將兩次查詢的結果按照按照兩張表的關聯進行合併。
在這次的查詢中,兩張表的唯一關聯應該是 users.id
與 topics.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);
得到如下結果。
哦耶,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);