我正在经历我的第一个Laravel项目,并且实现了一个资源收集API,在其中我通过护照获取数据。除了关系外,似乎可以从模型中正确检索数据。情况如下:
item.php(模型)
class MySerializer(ModelSerializer):
user_id = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), source='user', write_only=True)
class Meta:
model = Model1
fields = '__all__'
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');
}
}
这是有关获取的数据示例的屏幕:
如上所示,没有任何关系。通过像这样建议地搜索和更改代码:
<?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),
[...]
我仍然没有找回关系。 谁能给我一些帮助/提示来解决这个问题?
预先感谢您的帮助。
答案 0 :(得分:3)
下面的代码仅在显式加载时才显示Tipologie,以避免N + 1查询问题。
'tipologie' => TipologiaResource::collection($this->whenLoaded('tipologia'))
要加载Tipologie for Resource以显示它,您需要将其显式加载为:
$itemResource = new ItemResource($item->load('tipologia', ... other relationships...);
有关更多信息,请参见Eager Loading。
很抱歉,您不了解关系的类型,就像@ luca-cattide所说的那样,collectionTo不应使用collection,正确的用法是:
TipologiaResource::make($this->tipologia);
或者:
new TipologiaResource($this->topologia);
但是我建议您先使用“加载”方法加载信息,否则,您将在数据库中搜索“项目”,然后通过“ typologie”进行搜索,依此类推,直到加载所有关系。
还有另一种无需加载项目即可加载信息的方式,如下所示:
new ItemResource(App\Item::find(1)->with(['tipologie', ... other relationships ... ])->get());
详细了解N + 1个查询问题here。
答案 1 :(得分:1)
感谢@vinicius,但按照@CamiloManrique的this post的建议进行了更多搜索,我注意到在这些关系中,我试图从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)
通过这种方式,可以正确提取数据。
再次感谢您的提示。