Closed mahfoudfx closed 2 years ago
Please provide full reproducing code
Please provide full reproducing code
Which parts of code you exactly need?
I have checked with fresh installation of Nova 3.30.0 and the issue remains the same. When creating a relation via MorphTo
, the generated route is https://nova.test/nova-api/analyses/morphable/analysissurveyable?type=pcrannexs¤t=13302&first=false&search=&withTrashed=false&viaResource=&viaResourceId=&viaRelationship=&editing=true&editMode=create
, and the part &first=false
remains false regardless the Create or Edit operation. This route will return all the records, which in the case of +10K entry will take several seconds to load the relation.
To reproduce this, as I mentionned before, just use 2 models with a Polymorphic relation. I have reproduced it on my project by the simplifed following two models: Analysis and Pcrannex and re-generated their Nova Resources.
PS: For the Model 'Analysis' I've also tried without the use of Laravel\Nova\Actions\Actionable
to avoid any suspicion regarding this class.
Models Analysis Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Nova\Actions\Actionable;
class Analysis extends Model
{
use HasFactory;
use Actionable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'analysistype_id',
'patient_id',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'id' => 'integer',
'analysistype_id' => 'integer',
'patient_id' => 'integer',
];
public function analysistype()
{
return $this->belongsTo(\App\Models\Analysistype::class);
}
public function patient()
{
return $this->belongsTo(\App\Models\Patient::class);
}
public function analysissurveyable()
{
return $this->morphTo();
}
}
Pcrannex Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Pcrannex extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'purpose',
'suspect_contact',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'id' => 'integer',
'purpose' => 'integer',
'suspect_contact' => 'integer',
];
public function analysissurvey()
{
return $this->morphOne(\App\Models\Analysis::class, 'analysissurveyable');
}
}
Nova Resources Analysis Nova Resource
<?php
namespace App\Nova;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\MorphTo;
use Laravel\Nova\Http\Requests\NovaRequest;
class Analysis extends Resource
{
/**
* The model the resource corresponds to.
*
* @var string
*/
public static $model = \App\Models\Analysis::class;
/**
* The single value that should be used to represent the resource when being displayed.
*
* @var string
*/
public static $title = 'id';
/**
* The columns that should be searched.
*
* @var array
*/
public static $search = [
'id',
];
/**
* Get the fields displayed by the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function fields(Request $request)
{
return [
ID::make(__('ID'), 'id')->sortable(),
BelongsTo::make(__('Type'), 'analysistype', Analysistype::class)
->sortable()->withoutTrashed()->rules('required'),
BelongsTo::make(__('Patient'), 'patient', Patient::class)
->sortable()->searchable()->withSubtitles()->withoutTrashed()
->showCreateRelationButton()->rules('required'),
MorphTo::make(__('Survey'), 'analysissurveyable')->types([Pcrannex::class])
->searchable()->showCreateRelationButton()->hideFromIndex()
];
}
/**
* Get the cards available for the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function cards(Request $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function filters(Request $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function lenses(Request $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function actions(Request $request)
{
return [];
}
}
Pcrannex Nova Resource
<?php
namespace App\Nova;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Http\Requests\NovaRequest;
class Pcrannex extends Resource
{
/**
* The model the resource corresponds to.
*
* @var string
*/
public static $model = \App\Models\Pcrannex::class;
/**
* The single value that should be used to represent the resource when being displayed.
*
* @var string
*/
public static $title = 'id';
/**
* The columns that should be searched.
*
* @var array
*/
public static $search = [
'id',
];
/**
* Get the fields displayed by the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function fields(Request $request)
{
return [
ID::make(__('ID'), 'id')->sortable(),
Select::make(__('Purpose'), 'purpose')
->options(['1' => __('Diagnosis'), '2' => __('Screening'), '3' => __('Travel')])
->displayUsingLabels()->rules('required'),
Select::make(__('Suspect contact'), 'suspect_contact')
->options(['0' => __('Unkown'), '1' => __('Suspect')])
->rules('required')->displayUsingLabels(),
];
}
/**
* Get the cards available for the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function cards(Request $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function filters(Request $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function lenses(Request $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function actions(Request $request)
{
return [];
}
}
I can only reproduce the bug without ->searchable()
and even with a fix, it'll still load all information on editing the morph to relation.
If you still having issue with searchable()
I would assume you have an issue somewhere else and I don't have enough information to solve it.
I tested again with a fresh installation of Laravel and Nova as mentioned above, with only these models, with freshly generated resources using php artisan nova:resource
exactly as described above and I still get &first=false
.
The only quick fix that I found, is to hardcode shouldLoadFirstResource:function(){return true}
on the public/vendor/nova/app.js
.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Fixed in v3.31.0: https://nova.laravel.com/releases/3.31.0
Description: When I use InlineCreate for a polymorphic relation using the morphTo, the field takes long time to load the relationship. At the begining, the issue was not visible, but when the DB reached 12K entries, it takes up to 20s to load.
When I investigate the issue, I found that is similair to #2391.
I have dug deeper and followed the generated route by Nova:
https://nova.test/nova-api/analyses/morphable/analysissurveyable?type=pcrannex4s¤t=13296&first=false&search=&withTrashed=false&viaResource=&viaResourceId=&viaRelationship=&editing=true&editMode=create
I found that it requested all the records with format:{"resources":[{"display":"Annexe 4","value":13296},{"display":"Annexe 4","value":13295},{"display":"Annexe 4","value":13294},{"display":"Annexe 4","value":13293}.........
.Analyzing this route and the result, I suspected the part
&first=false
, which I have changed to&first=true
and it returned the last inserted relation. So, even if the field is->searchable()
, the generated route is wrong. Continuing the investigation by searching formorphable
, I found MorphToField.vue which contains this part that (line 383) I suspect is responsible to generate the concerned route.I didn't go deeper than that, but I suspect that the condition in the function
shouldLoadFirstResource()
will always return false and maybe revised toPlease confirm if this investigation is correct, will solve this issue and will not generate a conflict with other features especially in a multi-user environment.
Detailed steps to reproduce the issue on a fresh Nova installation:
Just use MorphTo with more than 10K entries relation table.