Подтвердить что ты не робот

Почему Laravel/Eloquent не может использовать JOIN для Eager Loading?

<?php

class Cat extends Eloquent {

    public function user() {
        return $this->belongsTo('User');
    }
}

class User extends Eloquent {

    public function cats() {
        return $this->hasMany('Cat');
    }
}

Сейчас:

$cats = Cat::with('user')->get();

Выполняет 2 запроса:

select * from `cats`
select * from `users` where `users`.`id` in ('1', '2', 'x')

Почему он не может этого сделать:

select * from cats inner join users on cats.user_id = users.id

Для тех, кто говорит, что в таблице есть оба столбца id, которые можно легко избежать с помощью псевдонимов:

select 
    c.id as cats__id,
    c.name as cats__name,
    c.user_id as cats__user_id,
    b.id as users__id,
    b.name as users__name
from cats c
inner join users b on b.id = c.user_id

ОБНОВЛЕНИЕ

Кто-то указал, что Eloquent не знает столбцов таблиц из моделей, но я предполагаю, что они могли бы предоставить способ определить их в модели, чтобы затем использовать псевдонимы и делать правильное соединение вместо дополнительного запрос.

4b9b3361

Ответ 1

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

class User extends Eloquent {

    public function cats() {
        return $this->hasMany('Cat');
    }

    public function dogs() {
        return $this->hasMany('Dog');
    }
}

Теперь мы хотим, чтобы они загружали их как с помощью пользователя:

$users = User::with('cats','dogs')->get();

Нет объединения, которое могло бы объединить их в один запрос. Однако выполнение отдельного запроса для каждого элемента "с" действительно работает:

select * from `users`
select * from `cats` where `user`.`id` in ('1', '2', 'x')
select * from `dogs` where `user`.`id` in ('1', '2', 'x') 

Таким образом, хотя эта методология может привести к дополнительному запросу в некоторых простых обстоятельствах, она обеспечивает возможность загружать более сложные данные, когда метод объединения будет терпеть неудачу.

Это мое предположение, почему это так.

Ответ 2

cats и users вероятно, оба имеют столбец с именем id, оставляя ваш предложенный запрос неоднозначным. При загрузке Laravel требуется дополнительный запрос, но он избегает этого потенциального сбоя.