laravel5.1 eloquent with 經過閉包篩選特定 field 得不到結果的問題

(圖片有點大,可右鍵新tab查看)php

 

User模型laravel

class User extends Model
{
    public function profile()
    {
        return $this->hasMany(UserProfile::class);
    }
}

  

使用with查詢某個user及其的profilesql

User::with(['profile' => function($query) {
            $query->select(['id']);
        }])->find(4)->toArray()

  

上面的用法中,咱們會發現,即便數據庫有記錄,sql也記錄了對應的查詢語句,可是profile關聯倒是空的,數據庫

 

可是加上外鍵就能夠獲得正確結果了:數組

User::with(['profile' => function($query) {
            $query->select(['id', 'user_id']);
        }])->find(4)->toArray()

  

能夠查找到正確的profile了。框架

 

這和 laravel 框架的工做方式相關,咱們先看看下面的例子:ui

咱們使用 DB::listen 方法去記錄相關的 sql 語句this

 

此次咱們不用find,用getspa

User::with('profile')->whereIn('id', [3, 4])
            ->get()->toArray()

  

咱們查看 log 能夠發現有如下語句:debug

select * from `tb_user` where `id` in (?, ?) [3,4] 
select * from `tb_user_profile` where `tb_user_profile`.`user_id` in (?, ?) [3,4] 

  

咱們能夠明顯發現,laravel 對於 user 和 user_profile 是獨立查詢的,

也就是說會獲得兩個集合,一個是 User、一個是 UserProfile,

可是這並非咱們想要的結果,咱們須要的結果是,只有一個 User 集合, 而且這個 User 集合裏面有 UserProfile 關聯。

 

可是結果就是這樣,若是是你,你會怎麼把這些數據關聯起來呢?

對了,咱們定義關聯的時候不是定義了它們的關聯方式麼?

上面的 hasMany 方法默認第二第三個參數其實就是這兩個集合創建關聯的關鍵,第三個參數 user_id、第四個參數 id;

這樣一來咱們就能夠經過比較 UserProfile 的 user_id 和 User 裏面的 id,若是相等,則這個 UserProfile 是屬於這個 User 的,咱們就把該 UserProfile 放進 User 的 profile 關聯中,最後就獲得咱們想要的結果了。

 

用xdebug證明一下咱們的想法:

如咱們所想的那樣,圖一的 match 方法,顧名思義就是匹配了,經過 user 模型集合和 profile 模型集合進行匹配。

圖二,也證明了咱們模型創建關聯須要經過關聯中外鍵的值得想法。

圖三,是經過獲取 user 的 localkey,也就是 id 的值,來查找 $dictonary 中是否有對應的值,buildDictonary 方法會創建一個關聯數組,key 是 user_id(外鍵)的值,值是關聯的數據。這樣同樣,因爲咱們沒有把 user_id 也select 出來,最後獲得的 $dictonary 的結構並非預期的那樣:

 

其實咱們原本是想要獲得下面的這種:

[
  3 => xxx(UserProfile對象)       // 3 是關聯的 user_id
]

可是咱們獲得的倒是,全部的 UserProfile 都在一個嵌套的數組裏面了,這樣一來,下面的 getRelationValue 獲得的結果天然就是空的了。

 

好了,總結一下,就是:laravel 先查詢主要的數據(不帶with),查詢完了以後,取出其中的 id 列數組(不必定都是id啊,只是舉個例子),將這個數組做爲條件去查找關聯,有多少個關聯就會再去查找多少次,查找完關聯以後經過獲得的結果的主鍵和關聯數據的外鍵比對,相等則創建關聯。

 

總結:在關聯篩選 field 的時候,也必需要把關聯的外鍵寫進去,不然,即便產生了正確的 sql 語句,可是它們創建不了關聯,經過 $user->profile 獲得的仍是一個空集合。

(對於全部關聯都有效哦)

相關文章
相關標籤/搜索