Жадная загрузка не работает для многих отношений Laravel Eloquent

У меня отношения «один ко многим» между двумя классами. Когда я пытаюсь получить дочерний элемент ownTo посредством активной загрузки, он не работает по какой-то странной причине. Согласно следующему, он должен работать: https://laravel.com/docs/master/eloquent-relationships#eager-loading

В таблицах есть, среди прочего, следующие столбцы (устаревшие, нет возможности изменить это). kasticket_.kassa_id и kassa.code относятся друг к другу:

kasticket_.ticketnr, kasticket_.kassa_id, ...
kassa.code, ...

Вот несколько упрощенные классы. ReceiptDetail:

<?php

namespace App;

use App\Pos;
use Illuminate\Database\Eloquent\Model;

class ReceiptDetail extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'kasticket_';

    /**
     * The primary key for the model.
     *
     * @var string
     */
    protected $primaryKey = 'ticketnr';

    /**
     * Get pos.
     */
    public function pos()
    {
        return $this->belongsTo(Pos::class, 'kassa_id', 'code');
    }
}

Поз:

<?php

namespace App;

use App\ReceiptDetail;
use Illuminate\Database\Eloquent\Model;

class Pos extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'kassa';

    /**
     * The primary key for the model.
     *
     * @var string
     */
    protected $primaryKey = 'code';

    /**
     * Get the receipt details.
     */
    public function receiptDetails()
    {
        return $this->hasMany(ReceiptDetail::class, 'kassa_id', 'code');
    }
}

В результате это дает значение null, а не модель Pos. В журнале запросов я вижу, что он загружается с нетерпением:

$receipts = \App\ReceiptDetail::with('pos')->get();
foreach ($receipts as $receipt) {
    dd($receipt->pos);
}

Это дает мне ожидаемую модель Pos, но был сделан дополнительный запрос к БД:

$receipts = \App\ReceiptDetail::with('pos')->get();
foreach ($receipts as $receipt) {
    dd($receipt->pos()->first());
}

Из журнала запросов я вижу следующее:

select * from `kasticket`
select * from `kassa` where `kassa`.`code` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

ReceiptDetail имеет одну запись pos (), верно?

DsRaj 20.07.2018 11:04

Таблица ReceiptDetail должна иметь pos_id в соответствии с тем, как вы установили это отношение. Вместо dd используйте dump и посмотрите результат для всех $receipts, которые вы выбрали. Может быть, у первого действительно pos_id нулевой.

d3jn 20.07.2018 11:07

@DsRaj, это правильно

Ruben Colpaert 20.07.2018 11:07

@RubenColpaert добавьте схему таблицы в свой вопрос

DsRaj 20.07.2018 11:09

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

Ruben Colpaert 20.07.2018 11:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
5
1 161
2

Ответы 2

Если вы не следуете правильному имени в первичном и внешнем ключах, вам необходимо правильно добавить отношения.

Измените так:

public function pos()
{
   return $this->belongsTo(Pos::class,'foreign_key', 'local_key');
}

Модель POS

public function receiptDetails()
{
   return $this->hasMany(ReceiptDetail::class,'foreign_key', 'local_key');
}

Больше информации

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

Ruben Colpaert 20.07.2018 12:15

Все это в оригинальном посте. Если я чего-то не упускаю?

Ruben Colpaert 20.07.2018 13:08

Уникальные идентификаторы таблиц (kasticket_.kassa_id и kassa.code) представляют собой строки в БД. Мне пришлось добавить следующую строку в класс Pos:

/**
 * Indicates if the IDs are auto-incrementing.
 *
 * @var bool
 */
public $incrementing = false;

Другие вопросы по теме