Ошибка загрузки Laravel "Попытка получить свойство необъекта в ... / BelongsToMany.php" - PullRequest
0 голосов
/ 01 апреля 2019

Laravel 5.8

У меня возникла проблема с интенсивной загрузкой для работы на некоторых моделях, но не на других.

С помощью ремесленника я могу запустить;

$p = App\Programme::find(34)->reviews

и получите правильный результат.Если я изменю это значение на

$p = App\Programme::with('reviews')->find(34)

, так что обзоры загружаются с нетерпением, произойдет сбой с ошибкой

PHP Notice:  Trying to get property of non-object in .../vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php on line 301

выход из ремесленника с журналом запросов, связывания и выполнениявремя

$p = App\Programme::with('destinations', 'reviews')->find(34)

"select * from `programmes` where `programmes`.`id` = ? and `programmes`.`deleted_at` is null limit 1"
array:1 [
  0 => 34
]
1.08


"select `destinations`.*, `programme_destination`.`programme_id` as `pivot_programme_id`, `programme_destination`.`destination_id` as `pivot_destination_id`, `programme_destination`.`created_at` as `pivot_created_at`, `programme_destination`.`updated_at` as `pivot_updated_at` from `destinations` inner join `programme_destination` on `destinations`.`id` = `programme_destination`.`destination_id` where `programme_destination`.`programme_id` in (34)"
[]
0.88


"select `reviews`.*, `programme_reviews`.`programme_id` as `pivot_programme_id`, `programme_reviews`.`review_id` as `pivot_review_id`, `programme_reviews`.`created_at` as `pivot_created_at`, `programme_reviews`.`updated_at` as `pivot_updated_at` from `reviews` inner join `programme_reviews` on `reviews`.`id` = `programme_reviews`.`review_id` where `programme_reviews`.`programme_id` in (34)"
[]
0.85

Последний запрос при запуске вручную работает просто отлично.

Я могу запустить точно такие же две команды, используя либо Пользователь или Направление моделей и получить успешный ответ.Таким образом, должно быть что-то другое в отношении $programme->reviews по сравнению с $programme->user или $programme->destinations

Вот мои модели (обрезанные до соответствующих функций);

Приложение \ BaseModel

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use OwenIt\Auditing\Contracts\Auditable;
use Log;
use DB;

class BaseModel extends Model
{
    protected $guarded = ['alias', 'created_at', 'updated_at', 'deleted_at', 'slug'];

    public $custom_attributes = [];
    public $index_attributes = ['alias', 'user'];


    public function alias()
    {
        return $this->morphOne('App\Alias', 'aliased');
    }

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

}

Приложение \ Программа

<?php

namespace App;

use App\BaseModel;
use Illuminate\Database\Eloquent\SoftDeletes;
use OwenIt\Auditing\Contracts\Auditable;
use Log;

class Programme extends BaseModel implements Auditable
{
    use SoftDeletes;
    use \OwenIt\Auditing\Auditable;


    protected $table = 'programmes';

    protected $dates = ['deleted_at'];


    function __construct(array $attributes = array())
    {
        parent::__construct($attributes);
    }

    public function destinations()
    {
        return $this->belongsToMany('App\Destination', 'programme_destination')
            ->withTrashed()
            ->withTimestamps();
    }

    public function reviews()
    {
        return $this->belongsToMany('App\Review', 'programme_reviews')
            ->withTrashed()
            ->withTimestamps();
    }
}

Приложение \ Обзор

<?php

namespace App;

use App\BaseModel;
use Illuminate\Database\Eloquent\SoftDeletes;
use OwenIt\Auditing\Contracts\Auditable;
use Log;

class Review extends BaseModel implements Auditable
{
    use SoftDeletes;
    use \OwenIt\Auditing\Auditable;

    protected $fillable = ['title', 'name', 'first_name', 'last_name', 'review_type', 'email_address', 'created_at'];


    function __construct(array $attributes = array())
    {
        parent::__construct($attributes);
    }

    public function programmes()
    {
        return $this->belongsToMany('App\Programme', 'programme_reviews')
            ->withTrashed()
            ->withTimestamps();
    }
}

Я могу запустить $p = App\Programme::with('destinations', 'alias')->find(34) успешно.Вот модель для пунктов назначения

App \ Destination

<?php

namespace App;

use App\BaseModel;
use Illuminate\Database\Eloquent\SoftDeletes;
use OwenIt\Auditing\Contracts\Auditable;


class Destination extends BaseModel implements Auditable
{
    use SoftDeletes;
    use \OwenIt\Auditing\Auditable;


    protected $table = 'destinations';

    protected $dates = ['deleted_at'];


    function __construct(array $attributes = array())
    {
        parent::__construct($attributes);
    }

    public function programmes()
    {
        return $this->belongsToMany('App\Programme', 'programme_destination')
            ->withTrashed()
            ->withTimestamps();
    }
}

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

Для справки здесь приведены базы данных создания кодов;

программ

CREATE TABLE `programmes` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(191) NOT NULL COLLATE 'utf8_unicode_ci',
    `destination_id` INT(10) UNSIGNED NULL DEFAULT NULL,
    `user_id` INT(10) UNSIGNED NOT NULL DEFAULT '1',
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL,
    `deleted_at` TIMESTAMP NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    INDEX `programmes_user_id_foreign` (`user_id`),
    INDEX `programmes_destination_id_foreign` (`destination_id`),
    CONSTRAINT `programmes_destination_id_foreign` FOREIGN KEY (`destination_id`) REFERENCES `destinations` (`id`),
    CONSTRAINT `programmes_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

рецензии

CREATE TABLE `reviews` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `title` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
    `name` VARCHAR(191) NOT NULL COLLATE 'utf8_unicode_ci',
    `first_name` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
    `last_name` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
    `email_address` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL,
    `deleted_at` TIMESTAMP NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

programme_reviews - многие ко многим

CREATE TABLE `programme_reviews` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `programme_id` INT(10) UNSIGNED NOT NULL,
    `review_id` INT(10) UNSIGNED NOT NULL,
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    INDEX `programme_reviews_review_id_foreign` (`review_id`),
    INDEX `programme_id` (`programme_id`),
    CONSTRAINT `programme_reviews_programme_id_foreign` FOREIGN KEY (`programme_id`) REFERENCES `programmes` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT `programme_reviews_review_id_foreign` FOREIGN KEY (`review_id`) REFERENCES `reviews` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

пунктов назначения

CREATE TABLE `destinations` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(191) NOT NULL COLLATE 'utf8_unicode_ci',
    `user_id` INT(10) UNSIGNED NOT NULL DEFAULT '1',
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL,
    `deleted_at` TIMESTAMP NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    INDEX `destinations_parent_id_index` (`parent_id`),
    INDEX `destinations_user_id_foreign` (`user_id`),
    CONSTRAINT `destinations_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

programme_destination один ко многим

CREATE TABLE `programme_destination` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `programme_id` INT(10) UNSIGNED NOT NULL,
    `destination_id` INT(10) UNSIGNED NOT NULL,
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    INDEX `programme_destination_programme_id_foreign` (`programme_id`),
    INDEX `programme_destination_destination_id_foreign` (`destination_id`),
    CONSTRAINT `programme_destination_destination_id_foreign` FOREIGN KEY (`destination_id`) REFERENCES `destinations` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT `programme_destination_programme_id_foreign` FOREIGN KEY (`programme_id`) REFERENCES `programmes` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

Единственная реальная разница между $programme->destinations и $programme->reviews заключается в том, что reviews является отношением многих ко многим.

1 Ответ

0 голосов
/ 02 апреля 2019

Так что я нашел ответ на этот щекотливый запрос благодаря внешней помощи.

Мой вопрос как есть, не был бы ответственным, поскольку проблема фактически существовала с переменной класса $pivot, которую я назначил для модели Программы (и удалил для поста, чтобы попытаться сократить его) .

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

Изменение $pivot на что-либо еще позволило правильно загрузить отношения.

Вряд ли у кого-то будет такая же проблема, как у меня, но кто знает, это может помочь кому-то избежать ошибки, с которой я столкнулся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...