Laravel 5.6 API 资源集合 - 未获取条件关系

2024-03-27

我正在体验我的第一个 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(资源)

<?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'))
        ];
    }
}

这是有关获取数据示例的屏幕:

如上所示,没有任何关系的痕迹。通过谷歌搜索并按照建议更改代码,如下所示:

// 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');
}

我仍然没有恢复关系。 谁能给我一些帮助/提示来解决这个问题?

预先感谢您的帮助。


下面的代码只会在显式加载时显示 Tipologie,以避免 N+1 查询问题。

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

要加载 Tipologie for Resource 来显示它,您需要将其显式加载为:

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

See 急切加载 https://laravel.com/docs/5.6/eloquent-relationships#eager-loading有关此的更多信息。

Edit

很抱歉不理解关系的类型,就像@luca-cattide所说,collection不应该用于belongsTo,正确的应该是使用:

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

Or also:

new TipologiaResource($this->topologia);

但我建议您之前使用“load”方法加载信息,否则您在数据库中搜索“item”,另一个搜索“typologie”,依此类推,直到加载所有关系。

还有另一种无需加载项目即可加载信息的方法,请参见下文:

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

查看更多有关 N+1 查询问题的信息here https://stackoverflow.com/questions/97197/what-is-the-n1-select-query-issue.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Laravel 5.6 API 资源集合 - 未获取条件关系 的相关文章

随机推荐