2017-01-26 2 views
2

Допустим, у нас есть таблицы dog и breed с соответствующими моделями:Эмуляция жадной загрузки с запросом

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" 
    } 

Есть ли способ, чтобы дать наш необработанный запрос приведет к тому же форматированию, что и результат нашей Eloquent, без необходимости этого делать?

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, возвращение именно того, чего вы хотите, на самом деле не так реально.

AFAIK MySQL не поддерживает массивы, но в Postgres вы можете выбрать информацию о породе в массиве, но даже тогда вы не можете использовать элементы массива.

Вы можете выбрать все, как JSON:

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

Но опять же, манипуляция ценности является намного больше усилий, чем это было бы просто реализовать требуемую функциональность в коде, а не SQL.

Смежные вопросы