Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Inline Morph To Laravel Package

digital-creative/nova-inline-morph-to

A Laravel Nova field for inline morphTo editing: create and update polymorphic related records directly from the parent resource form, without leaving the page. Streamlines data entry and polymorphic relationship workflows in Nova.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the field with Composer alongside Nova:

composer require digital-creative/nova-inline-morph-to

There is no config file or migration step — the package is a single Nova field class plus compiled JS assets, so the fastest way to understand it is to read src/InlineMorphTo.php and the short README example, then copy that example straight into a resource.

The first, most natural use case is a polymorphic "owner" relation on a secondary model: a Comment that belongs to either a Post or a Video, a Note that belongs to a Contact or Company, or an Image that belongs to any number of content types. The field lets the Nova user pick the morph type and create/edit the related model's fields inline, without navigating away to another resource.

Minimal wiring — replace the native Nova MorphTo field on the child resource:

use DigitalCreative\InlineMorphTo\InlineMorphTo;

public function fields(NovaRequest $request)
{
    return [
        Text::make('Body'),

        InlineMorphTo::make('Commentable')
            ->types([
                Post::class,
                Video::class,
            ])
            ->fields([
                Text::make('Title')->rules('required'),
                Textarea::make('Body')->rules('required'),
            ]),
    ];
}

Start by testing on a simple two-type morph, then expand. Check the package's composer.json for the supported Nova major version before installing; releases track Nova 4/5, so lock to a tag that matches your Nova install.

Implementation Patterns

Type-scoped field sets. Most real-world morphs have different attributes per type (a Post has a title, a Video has a URL). Define separate field arrays per morph class so validation and UI stay honest:

InlineMorphTo::make('Attachable')
    ->types([
        Post::class  => [Text::make('Title')],
        Video::class => [Text::make('Url'), Text::make('Duration')],
    ]);

Use this pattern whenever the underlying models diverge; sharing one field list across heterogeneous types leads to confusing validation errors.

Validation belongs on the inline fields, not the parent field. Put ->rules() and ->creationRules() on the nested fields. The parent InlineMorphTo only needs ->required() to force a type selection; conditional rules that reference sibling fields work because Nova submits everything in one request.

Reuse field factories. Because the field list is plain PHP, extract it to a method or a Fields helper class and share it with the child resource:

->fields(PostResource::inlineFields())

This keeps the standalone "create post" page and the inline form in sync — otherwise you will fix a validation rule in one place and forget the other.

Index and detail views. On index/detail the field renders the related resource's title, so ->showOnIndex() / ->onlyOnDetail() behave as expected. Keep it onlyOnForms() for resources where loading the morph on every row is expensive.

Dynamic type lists. ->types() is evaluated per-request, so you can filter by policy or config:

->types(array_filter(
    [Post::class, Video::class],
    fn ($class) => Gate::allows('create', $class::newModel())
))

This is the cleanest way to avoid presenting types the user cannot create.

Combine with dependency containers. Nested fields are standard Nova fields, so dependsOn() and conditional display inside the inline block work — useful for country/state style fields inside the morph target.

Gotchas and Tips

  • The morph target must have a Nova resource. The field resolves labels and default fields through Nova::newResourceFromModel(). An unregistered model produces a blank or broken type.
  • Morph type column must be fillable / cast correctly. The field writes commentable_type and commentable_id in one request; if your model's $fillable or morphTo() name differs from the field's make() argument, the relation silently saves nothing.
  • Authorization is not automatic. Nova checks the parent resource policy, but inline creation of the related model still needs a create policy on that model's resource. Missing policies surface as a generic 403 on submit, not a field-level error — inspect the network tab first.
  • Attribute name collisions. Inline fields share the request payload with the parent form. Do not name a nested field identically to a parent column (name inside a Post morph on a User resource, for example) unless you deliberately want that hydration.
  • Updating vs creating. Existing morph targets render editable inline; new ones render empty. If you only want create-inline, gate with ->hideWhenUpdating() and test the update path explicitly — this is the least-covered code path in a 34-star package.
  • Community size is a risk. With ~34 stars and zero dependents, you are effectively on a maintained-by-few library. Pin the exact version in composer.json, keep an upgrade test in your suite, and be ready to fall back to a two-field native MorphTo + BelongsTo pair if a Nova upgrade breaks it.
  • Debugging asset issues. If the UI renders blank after a Nova upgrade, check that the package's published JS in vendor/.../dist is being loaded; the compiled assets are not rebuilt by npm in your app. Re-running composer update is usually enough, but a hard php artisan nova:publish clears stale copies.
  • Extension point: custom field rendering. Because every field in the inline block is a normal Nova field, subclassing InlineMorphTo and overriding its field resolution is straightforward if you need per-type layouts — but check src/ first rather than forking; the class is small and readable.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect