I'm working on a Laravel project with Nova 4 and I'm struggling to create a User with the role 'instructor' and their associated InstructorProfile in a single step using Nova's admin interface. It's crucial that both records are created simultaneously, not in separate steps.
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('firstName');
$table->string('surname');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->enum('role', ['admin', 'instructor', 'normal'])->default('normal');
$table->index('email');
$table->index('role');
$table->rememberToken();
$table->timestamps();
});
Schema::create('instructor_profiles', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('phoneNumber')->nullable();
$table->text('bio')->nullable();
$table->text('qualifications')->nullable();
$table->string('photo')->nullable();
$table->timestamps();
});
I've attempted to override the fill()
method in my Nova resource:
class InstructorProfile extends Resource
{
public static $model = \App\Models\User::class;
public static $title = 'firstName';
public static $search = [
'id', 'user.firstName', 'user.surname', 'user.email',
];
public static function indexQuery(NovaRequest $request, $query)
{
return $query->where('role', 'instructor');
}
public static $with = ['instructorProfile'];
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),
Text::make('First Name', 'firstName')
->sortable()
->rules('required', 'max:255'),
Text::make('Surname')
->sortable()
->rules('required', 'max:255'),
Email::make('Email')
->sortable()
->rules('required', 'email', 'max:254')
->creationRules('unique:users,email')
->updateRules('unique:users,email,{{resourceId}}'),
Password::make('Password')
->onlyOnForms()
->creationRules('required', 'string', 'min:8')
->updateRules('nullable', 'string', 'min:8'),
Hidden::make('Role')
->default('instructor'),
Text::make('Phone Number',"instructor.phoneNumber") ,
Textarea::make('Bio',"instructor.bio")
->nullable()
->hideFromIndex(),
Textarea::make('Qualifications',"instructor.qualifications")
->nullable()
->hideFromIndex(),
Image::make('Photo',"instructor.photo")
->disk('public')
->path('instructor-photos')
->prunable()
->deletable(),
];
}
public static function fill(NovaRequest $request, $model)
{
$model = parent::fill($request, $model);
$model->instructorProfile()->create([
'created_by' => auth()->id(),
'bio' => $request->instructor_bio,
'phoneNumber' => $request->instructor_phoneNumber,
'qualifications' => $request->instructor_qualifications
]);
return $model;
}
However, this doesn't work because $model doesn't seems even User in this case and it's just an array.
How can I modify my Nova resource to create both the User and InstructorProfile records in a single operation when using Nova's admin interface?
I need a way to create both records simultaneously within Nova and never in two steps or two resources.
Try using the HasOne field, this should allow you to create an Instructor Profile when creating the Instructor
use Laravel\Nova\Fields\HasOne;
HasOne::make('Instructor Profile'),