Коллекция ресурсов API Laravel 5.6 - условное отношение не получено - PullRequest
0 голосов
/ 04 сентября 2018

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

item.php (модель)

<?php

// Definizione Namespace
namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * Classe Item
 */
class Item extends Model
{
    use SoftDeletes;

    // Dichiarazione Proprietà
    protected $table = 'item';
    protected $dateformat = 'Y-m-d';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'data_acquisto',
        'labeled',
        'estensione_garanzia',
        'stato',
        'data_dismissione',
        'note'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'codice',
        'serial',
        'componente_id',
        'tipologia_id',
        'condizione_id',
        'locazione_id',
        'fornitore_id',
        'parent_id'
    ];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = [
        'data_acquisto',
        'data_dismissione',
        'deleted_at'
    ];

    /**
     * All of the relationships to be touched.
     *
     * @var array
     */
    protected $touches = [
        'componenti',
        'condizioni',
        'fornitori',
        'locazioni',
        'tipologie'
    ];

    /**
     * Scope query item figli
     * Getter
     * @param array $query Query
     * @return array Query
     */
    public function scopeFigli($query)
    {
        return $query->where('parent_id', '!=', null);
    }

    /**
     * Componenti Correlati
     * Getter
     * @return object Componenti
     */
    public function componenti()
    {
        // Definizione relazione
        return $this->belongsTo('App\Componente');
    }

    /**
     * Condizioni Correlate
     * Getter
     * @return object Condizioni
     */
    public function condizioni()
    {
        // Definizione relazione
        return $this->belongsTo('App\Condizione');
    }

    /**
     * Fornitori Correlati
     * Getter
     * @return object Fornitori
     */
    public function fornitori()
    {
        // Definizione relazione
        return $this->belongsTo('App\Fornitore');
    }

    /**
     * Locazioni Correlate
     * Getter
     * @return object Locazioni
     */
    public function locazioni()
    {
        // Definizione relazione
        return $this->belongsTo('App\Locazione');
    }

    /**
     * Tipologie Correlate
     * Getter
     * @return object Tipologie
     */
    public function tipologie()
    {
        // Definizione relazione
        return $this->belongsTo('App\Tipologia');
    }
}

item.php (Resource)

<?php

// Definizione Namespace
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Componente as ComponenteResource;
use App\Http\Resources\Condizione as CondizioneResource;
use App\Http\Resources\Fornitore as FornitoreResource;
use App\Http\Resources\Locazione as LocazioneResource;
use App\Http\Resources\Tipologia as TipologiaResource;

class Item extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        parent::toArray($request);

        return [
            'id' => $this->id,
            'codice' => $this->codice,
            'data_acquisto' => $this->data_acqisto,
            'serial' => $this->serial,
            'labeled' => $this->labeled,
            'estensione_garanzia' => $this->estensione_garanzia,
            'stato' => $this->stato,
            'data_dismissione' => $this->data_dismissione,
            'note' => $this->note,
            'parent_id' => $this->parent_id,
            // Includi associazioni se caricate
            'componenti' => ComponenteResource::collection($this->whenLoaded('componenti')),
            'condizioni' => CondizioneResource::collection($this->whenLoaded('condizioni')),
            'fornitori' => FornitoreResource::collection($this->whenLoaded('fornitori')),
            'locazioni' => LocazioneResource::collection($this->whenLoaded('locazioni')),
            'tipologie' => TipologiaResource::collection($this->whenLoaded('tipologie'))
        ];
    }
}

Это экран с примером полученных данных:

enter image description here

Как показано выше, никаких следов отношений нет. Путем поискать в Google и изменить код в соответствии с приведенным ниже предложением:

// Resoruce - Straight including relations instead of lazy load
[...]
'componenti' => ComponenteResource::collection($this->componenti),
[...]

или путем использования внешнего ключа в модели:

/**
 * Componenti Correlati
 * Getter
 * @return object Componenti
 */
public function componenti()
{
    // Definizione relazione
    return $this->belongsTo('App\Componente', 'componente_id');
}

Я все еще не получаю отношения. Может ли кто-нибудь дать мне небольшую помощь / совет для решения этой проблемы?

Заранее спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Спасибо @vinicius, но немного погуглил, как подсказывает этот пост @ 1002 * @CamiloManrique, я заметил, что в этих отношениях я пытаюсь получить данные со стороны belongs_to (так фактически с Item, а не с Componente, Tipologia и т. д.). Так как ::collection просто не работает, за исключением случаев, когда вызывается hasMany стороной отношения

Итак, вместо использования ::collection в сочетании с whenLoaded я произвел рефакторинг следующим образом:

    // Includi associazioni se caricate
    'componente' => ComponenteResource::make($this->componente),
    'condizione' => CondizioneResource::make($this->condizione),
    'fornitore' => FornitoreResource::make($this->fornitore),
    'locazione' => LocazioneResource::make($this->locazione),
    'tipologia' => TipologiaResource::make($this->tipologia)

Таким образом, данные выбираются без ошибок.

Еще раз спасибо за ваши советы.

0 голосов
/ 04 сентября 2018

Код ниже покажет Tipologie только тогда, когда он явно загружен, чтобы избежать проблем с N + 1 запросами.

'tipologie' => TipologiaResource::collection($this->whenLoaded('tipologia'))

Чтобы загрузить Tipologie for Resource, чтобы показать его, вам нужно явно загрузить его как:

$itemResource = new ItemResource($item->load('tipologia', ... other relationships...);

См. Eager Loading для получения дополнительной информации об этом.

Редактировать

Извините, что не понимаете тип отношений, как сказал @ luca-cattide, коллекция не должна использоваться для ownTo, и правильное использование:

TipologiaResource::make($this->tipologia);

Или также:

new TipologiaResource($this->topologia);

Но я советую вам использовать метод «load» для загрузки информации раньше, в противном случае вы выполняете поиск в базе данных «item», другой по «typologie» и т. Д., Пока не загрузите все ваши отношения.

Существует еще один способ загрузки информации без необходимости загрузки элемента, см. Ниже:

new ItemResource(App\Item::find(1)->with(['tipologie', ... other relationships ... ])->get());

Подробнее о проблемах с N + 1 запросом здесь .

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