Неопределенное свойство в методе доступа к фреймворку laravel - PullRequest
0 голосов
/ 09 января 2019

Мне нужна твоя помощь. Я работаю с Laravel Framework и у меня возникли проблемы с отношениями "принадлежат". В моем проекте есть таблицы, адресная книга и типы доставки, столбцы в таблицах:

address_book Я бы название почта delivery_1 deliverytype_id_1 delivery_2 deliverytype_id_2 ...

delivery_types Я бы название ...

Код модели типов доставки таков:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class DeliveryType extends Model
{
    protected $table = 'delivery_types';

    protected $guarded = ['id'];
}

Это модель адресной книги:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class AddressBook extends Model
{
    protected $table = 'address_book';  // table
    protected $guarded = ['id'];    // primary key
    protected $appends = ['delivery', 'actions'];   // accessors

    protected $delivery = '';

    public function del1() {
        return $this->belongsTo('App\DeliveryType', 'deliverytype_id_1', 'id')->withDefault();
    }

    public function del2() {
        return $this->belongsTo('App\DeliveryType', 'deliverytype_id_2', 'id');
    }


    /**
    * Accessor: get the actions column information.
    *
    * @return string
    */
    public function getActionsAttribute() {
        $actions = '<a href='. route('admin.addressbook.show', $this->id) .'>'.
                    'show<i class="livicon" data-name="info" data-size="18" data-loop="true" data-c="#428BCA" data-hc="#428BCA" title="view contact"></i></a>';
        return $actions;
    }

    /**
    * Accessor: get the deliveries information.
    *
    * @return string
    */
    public function getDeliveryAttribute () {
        $deliveries = [
            ['val' => $this->delivery_1, 'type' => $this->del1()->name], //row error
            ['val' => $this->delivery_2, 'type' => $this->del2()->name]
        ];

        foreach($deliveries as $delivery) {
            $this->delivery = (strlen($delivery['val']) > 0) ? 
                $this->appendString($this->delivery, '<strong>'.$delivery['type'].'</strong> '.$delivery['val']) : 
                $this->delivery;
        }
        return $this->delivery;
    }

    protected function appendString(string $str, string $val) {
        return (strlen($str) > 0) ? $str.'<br>'.$val : $val;
    }

На html-странице данные загружаются через ajax-вызов функции контроллера. Это код функции:

public function data(Request $request) {

        // Init data
        $this->addressbooks = AddressBook::get(
                ['address_book.id',
               'address_book.name',
               'address_book.email',
               'address_book.delivery_1',
               'address_book.delivery_2');

        // Return json array
        header("Content-Type: application/json");
        return $this->addressbooks;
    }

Когда страница вызывает функцию через ajax, фреймворк возвращает ошибку «Неопределенное свойство» в методе доступа getDeliveryAttribute, где я пытаюсь вызвать отношение относится к типу доставки ID и его ссылке в таблице типов доставки. .

Что я делаю не так? Заранее спасибо тем, кто может мне помочь.

1 Ответ

0 голосов
/ 10 января 2019

Вот как бы я написал модель Адресной книги

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

//use Illuminate\Support\Facades\Log;

class AddressBook extends Model
{
    protected $table = 'address_book';  // table

    //protected $guarded = ['id'];    // primary key

    // always load these accessors
    protected $appends = [
        'delivery',
        'actions',
    ];

    protected $mail    = '';

    // No need for $delInfo, use $this->delivery (same data)
    // protected $delInfo = '';

    public function category() {
        /*
            You can use `AddressBookCategory::class` instead of `'App\DeliveryType'`

            http://php.net/manual/en/migration55.new-features.php#migration55.new-features.class-name

            Because models are in the same napespace, we don't need to write \App\AddressBookCategory
         */
        return $this->belongsTo(AddressBookCategory::class, 'address_book_category_id', 'id');
    }

    public function deliveryType1() {
        return $this->belongsTo(DeliveryType::class, 'deliverytype_id_1', 'id')
                    /*
                        Specify empty string for the name, so that when we access
                        $this->deliveryType1->name it's equal ''
                     */
                    ->withDefault(['name' => '']);
    }

    public function deliveryType2() {
        return $this->belongsTo(DeliveryType::class, 'deliverytype_id_2', 'id')
                    ->withDefault(['name' => '']);
    }

    /**
    * Accessor: get the actions column information.
    *
    * Access by using: $this->action
    * 
    * @return string
    */
    public function getActionsAttribute() {
        // moved this into multi line, easier to read
        return '<a href='. route('admin.addressbook.show', $this->id) .'>'
                 .'show'
                 .'<i class="livicon" data-name="info" data-size="18" data-loop="true" data-c="#428BCA" data-hc="#428BCA" title="view contact"></i>'
              .'</a>';
    }

    /**
    * Accessor: get the deliveries information
    *
    * Access by using: $this->delivery
    *
    * @return string
    */
    public function getDeliveryAttribute () {
        // I've updated logic here, it should be easier to read...
        $delivery = [];

        if ( ! empty($this->delivery_1) ) {
            $delivery[] = '<strong>'.$this->deliveryType1->name.'</strong> '.$this->delivery_1;
        }

        if ( ! empty($this->delivery_2) ) {
            $delivery[] = '<strong>'.$this->deliveryType2->name.'</strong> '.$this->delivery_2;
        }

        // join array elements with a string `<br>`
        return implode('<br>', $delivery);
    }

}
...