Laravel ограниченные отношения не вернут данные - PullRequest
3 голосов
/ 26 апреля 2020

Я использую Laravel 7, и я столкнулся с проблемой, когда мои ограниченные отношения не возвращают никаких данных:

Домен. php

class Domain extends Model
{
    ...
    public function draws()
    {
        return $this->hasMany('App\Draw');
    }

Код в контроллере:

    DB::enableQueryLog();

    $domain = Domain::with(['draws' => function ($query) {
        $query->select(DB::raw('DATE(created_at) as date'), 'ball_1')
            ->groupBy('date', 'ball_1');
    }])->get();

    dump($domain->first()->draws); // <---- Should return 2 elements
    dd(DB::getQueryLog());

Выход

Illuminate\Database\Eloquent\Collection {#336 ▼
  #items: [] // <------- returns no elements
}
array:2 [▼
  0 => array:3 [▼
    "query" => "select * from `domains`"
    ...
  ]
  1 => array:3 [▼
    "query" => "select DATE(created_at) as date, `ball_1` from `draws` where `draws`.`domain_id` in (1) group by `date`, `ball_1`"
    ...
  ]
]

Если я выполню второй запрос, я могу получить оба ожидаемых элементы: Query in Adminer

Что я тут не так делаю?

1 Ответ

2 голосов
/ 27 апреля 2020

Это происходит потому, что вы не выбрали столбец внешнего ключа.

Laravel готовая загрузка для отношения hasMany загружается следующим образом:

Сначала выполняется один запрос к основной модельный стол, в вашем случае domains стол. Получив результаты, он возвращает массив первичных ключей (список из столбца id), например, 1, 2, 3

. С помощью этих идентификаторов он запросит связанную таблицу с предложением where в:

where domain_id in (1, 2, 3)

Будет возвращен список всех draws для загруженных доменов. Но этот список еще не связан с доменом. Он будет использовать столбец domain_id из второго запроса, чтобы узнать, какой draw принадлежит каждому domain.

Если вы не выбрали domain_id, он не сможет сделать последний шаг (domain_id будет нулевым для всех др aws)

Так что вам нужно добавить domain_id к вашему выбору:

Domain::with(['draws' => function ($query) {
    $query->select(DB::raw('DATE(created_at) as date'), 'ball_1', 'domain_id')
        ->groupBy('date', 'ball_1');
}])->get();

Или, возможно (не проверено) вы можете просто использовать addSelect() вместо select(), так как он не удалит исходные селекты, созданные Laravel:

Domain::with(['draws' => function ($query) {
    $query->addSelect(DB::raw('DATE(created_at) as date'), 'ball_1')
        ->groupBy('date', 'ball_1');
}])->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...