2017-01-26 108 views
2

比方說,我們有表dogbreed與相應型號:仿效預先加載與查詢

class Dog extends Model { 
    protected $table = 'dogs'; 
    protected $fillable = [ 
     'name', 'breed_id' 
    ]; 
    protected $hidden = [ 'breed_id' ]; 

    public function breed() { 
     return $this->belongsTo(Breed::class, 'breed_id'); 
    } 
} 

class Breed extends Model { 
    protected $table = 'breeds'; 
    protected $fillable = [ 
     'name' 
    ]; 
} 

我們渴望加載和訪問的品種是這樣的:

$dogs = Dog::with('breed')->all(); 

如果我們有一個API函數返回這個狗的集合,默認情況下它會爲墊他們作爲JSON,每個狗對象將有一個「品種」的對象:

{"dogs":[ 
    { 
     "id": 1, 
     "name": "Rover", 
     "breed": { 
       "id": 1, 
       "name": "Golden Retriever" 
       } 
    } 
    //etc 

現在,讓我們說,我們需要使用原始查詢(這是一個簡單的例子,請假裝有一個很好的加載狗我們使用原始查詢的原因)。我們可以用搶的品種名稱的JOIN:

$query = "SELECT dogs.*, breeds.name AS breed_name 
      FROM dogs 
      JOIN breeds ON dogs.breed_id = breeds.id"; 
$dogs = DB::select(DB::raw($query)); 

但是,如果我們回到這是JSON,它會具有不同的結構:

{"dogs":[ 
    { 
     "id": 1, 
     "name": "Rover", 
     "breed_id": 1, 
     "breed_name": "Golden Retriever" 
    } 

有沒有什麼辦法讓我們的原始查詢導致與我們的雄辯模型結果相同的格式,而無需執行此操作?

foreach ($dogs as $dog) { 
    $dog['breed'] = array(
     'id' = $dog['breed_id'], 
     'name' => $dog['breed_name'] 
    ); 
    unset($dog['breed_id']); 
    unset($dog['breed_name']); 
} 
return $dogs; 

我問,因爲我不想讓客戶端應用程序必須依賴於特定的API函數是否使用雄辯與預先加載,或者使用原始查詢解析結果以兩種不同的方式。

+0

我認爲你需要創建一個類似於第一個數組來轉換並以預定方式返回json的數組。首先得到狗,然後得到繁殖,並使數組結構與第一個相同,並使結果json。 – webDev

+0

@ShaileshSingh在問題的最底部,我舉了一個你正在描述的例子。我不想走這條路線,因爲這意味着我們必須迭代集合中的每個項目並重新格式化它,這是一個緩慢的過程 – user45623

回答

1

即使數據庫具有非常好的JSON支持,確切地返回你想要的並不是那麼可行。 AFIK MySQL不支持數組,但是在Postgres中你可以選擇一個數組中的品種信息,但即使這樣你也不能鍵入數組的元素。

您可以選擇一切,JSON:

-- Postgres Example 
SELECT row_to_json(row(dogs.*, ARRAY[breeds.name, breeds.id])) FROM ... 

但同樣,鍵控值比這將是剛剛實現代碼,而不是SQL所需功能的方式更多的努力。