Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kichetof's avatar

Extract Fields to invokable class

Hello,

I tried to extract my fields that same between main Resource and Lens filter.

That's my files for example. Do you have any idea? Many thanks for your help!

Cheers Tof

Nova resource Users

<?php

namespace App\Nova;

use App\Nova\Lenses\UserTrend;

class User extends Resource
{
    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @return array
     */
    public function fields(NovaRequest $request)
    {
        // doesn't work
        return [
            FieldCollection::make([
                new UserFields(),
            ])
        ];
        // doesn't work
        return [
            new UserFields(),
        ];
        // works!
        return [
            ID::make()->sortable(),

            Gravatar::make()->maxWidth(50),

            Text::make('Name')
                ->sortable()
                ->rules('required', 'max:255'),

            // other fields
        ];
    }

    /**
     * Get the lenses available for the resource.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @return array
     */
    public function lenses(NovaRequest $request)
    {
        return [
            new UserTrend()
        ];
    }
}

Lens UserTrend

<?php

namespace App\Nova\Lenses;

use App\Nova\UserFields;

class UserTrend extends Lens
{
    /**
     * Get the fields available to the lens.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @return array
     */
    public function fields(NovaRequest $request)
    {
        // doesn't work
        return [
            new UserFields(),
        ];

        // works!
        return [
            ID::make()->sortable(),

            Gravatar::make()->maxWidth(50),

            Text::make('Name')
                ->sortable()
                ->rules('required', 'max:255'),

            // other fields
        ];
    }
}

invokable class UserFields

<?php

namespace App\Nova;

use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\Gravatar;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Password;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;

class UserFields
{
    public function __invoke(NovaRequest $request)
    {
        return [
            ID::make()->sortable(),

            Gravatar::make()->maxWidth(50),

            Text::make('Name')
                ->sortable()
                ->rules('required', 'max:255'),

            Text::make('Email')
                ->sortable()
                ->rules('required', 'email', 'max:254')
                ->creationRules('unique:users,email')
                ->updateRules('unique:users,email,{{resourceId}}'),

            Password::make('Password')
                ->onlyOnForms()
                ->creationRules('required')
                ->updateRules('nullable'),

            Boolean::make('Admin')
                ->displayUsing(function ($admin) use ($request) {
                    return $request->user()->is_super_admin;
                }),
        ];
    }
}
``
0 likes
3 replies
formfeed's avatar
formfeed
Best Answer
Level 1

As I said on discord, try the following:

	    $fields = new UserFields;
        return FieldCollection::make(
                $fields($request);
            );
        // or
	    $fields = new UserFields;
        return  $fields($request);

You have varying degrees of nested arrays here. Your first example is the same as

return [FieldCollection[[field1, field2]]]

Your second example:

return [[field1. field2]]

Hopefully this will work, come back if its still not working.

Edit: Also you're not actually passing your $request object into your invokable, so your Admin boolean wont work, and youre using __invoke incorrectly. Try one of the above

kichetof's avatar

@formfeed Many thanks for your help!

I tried return new UserFields($request); but __invoke was not called. Your solution works very well! 😁

$fields = new UserFields;
 return  $fields($request);

But, I want inline call 🤩 I finally found the solution:

return call_user_func(new UserFields, $request);

Thanks for your great help!

Please or to participate in this conversation.