alisaleem27/nova-morph-to-create-field
A Laravel Nova field that adds inline creation to MorphTo relationships. Choose the morph type, fill in the related model's fields, and attach it without leaving the resource form, saving extra navigation and speeding up data entry.
What this actually is. A single-purpose Laravel Nova field: a PHP field class plus a Vue component that extends the stock MorphTo relationship field with an inline "create" modal. It adds no service layer, no migrations, no queues, and no persistence of its own — it is a UI affordance that issues create requests against Nova's existing endpoints. That matters for scoping: the failure surface is the admin panel and the create requests it fires, not the application's data model.
Architecture fit. Good, if and only if the product is already on Nova and already models polymorphic relations. Nova's native MorphTo has no create-in-place affordance, so the package fills a real gap in the operator workflow: attach a new parent record without abandoning a half-completed child form. The alternative is a hand-built custom field, which is materially more expensive than it looks because it requires both a PHP field class and a matching Vue component kept in sync with Nova's front-end contract. The package is a plausible shortcut past that cost.
Integration feasibility — conditional. The binding constraint is Nova itself: closed-source, license-gated, and version-sensitive. At 1 star and 0 dependents, assume the package was built against one Nova major and never validated forward. Feasibility must be established empirically — read composer.json for the declared Nova constraint, then read src/ end-to-end. It is small enough that a half-day of engineering review yields a real answer rather than an estimate.
Technical risk — high, concentrated in stewardship rather than code. The risk table a TPM should carry into the decision:
| Risk | Severity | Why it matters to the plan | Mitigation |
|---|---|---|---|
| Single maintainer, no release cadence | High | No one is obligated to fix anything, ever | Vendor or fork into an internal namespace; assign an owner |
| Zero community validation | High | No crowd-sourced signal that it works in the wild | Read the source; write our own feature tests before adoption |
| Nova major upgrade breaks the Vue build | High | Upgrade becomes an unbudgeted fork-maintenance task | Pin Nova; log it as explicit upgrade debt |
| Inline create bypasses Nova policies | High | Privilege escalation in the admin panel | Verify it defers to policies; wrap in canSee/gate regardless |
| Morph map alias vs. FQCN mismatch | Medium | Field renders empty and looks like a bug | Enforce Relation::enforceMorphMap app-wide first |
| Field used on index view | Medium | N+1 per morph type; broken UX | Restrict to form/detail contexts |
Key questions — answer from source, not from the README. (1) Which Nova/Laravel/PHP versions are supported and exercised? (2) Does the create flow route through Nova resource authorization, or does it issue creates directly against the model? (3) How is morph type → target Nova resource resolved — convention, morphMap, or explicit config? (4) Does it preserve searchable, nullable, morphWith, and morphWithCount semantics from the parent field? (5) Are there tests, and is there a CI matrix? Any "no" or "unknown" is a documented residual risk, not a blocker — but the authorization answer gates whether this proceeds at all.
TPM read. This is a candidate for a bounded internal-tooling investment, not a platform dependency. The decision is not "is this package good" — at this adoption level the answer is unknowable — but "can we own forty lines of code if we have to." If engineering says yes, the package is a cheap way to test whether inline morph creation actually moves operator throughput. If engineering says no, stop here and budget the in-house field.
Stack fit. Requires Nova as a licensed dependency; everything else (PHP, Laravel, the morph relation) is already present in a Nova shop. The package is additive — composer require, provider auto-discovery, one line in a Resource's fields() method. There is no schema change, no backfill, and no data migration, which is why the integration cost is dominated by review and testing time rather than build time.
Preconditions before any code lands. These are cheap and prevent the majority of field failures:
Relation::enforceMorphMap([...]) declared application-wide, so *_type columns hold stable aliases rather than FQCNs. Without this, the field's type resolution and our validation rules will silently disagree.composer.json; no floating dev-main.src/ that establishes the actual FQCN and public setters. Namespaces in packages at this maturity routinely diverge from the README; thirty seconds of composer show and head -20 src/*.php prevents an hour of Class not found.Placement and migration path. Site the field on the child side of the polymorphic relation only — the resource that owns the morphTo() — and scope it to create contexts. The recommended split: MorphToCreate on create/attach requests, stock MorphTo on update. That confines exposure to the third-party field to the one flow where it adds value and leaves the battle-tested Nova field governing re-parenting. Where the packaged field offers a type whitelist, use it; where it doesn't, enforce allowed types server-side with Rule::in([...]) against morph aliases.
Compatibility and sequencing. Sequence the work so each step is independently reversible:
*_type/*_id pairs, plus an authorization test proving a user without the parent-model create ability cannot create it inline.app/Nova/Fields/ and drop the dependency.Rollback is trivial and should be stated as such. Reverting to stock MorphTo is a one-line resource change; no data was restructured. That low downside is the main argument for running the pilot at all.
Maintenance ownership. This is the core operational fact: with one maintainer and zero dependents, upstream is effectively dormant. Assume no fixes, no security patches, no Nova-major compatibility work. The team must therefore take ownership at adoption time — either by vendoring the field class into the application namespace and removing the composer dependency, or by maintaining a pinned fork. Framing it as "we are adopting code, not a vendor relationship" sets the right expectation. Budget realistically: an initial audit plus a modest annual allowance for Nova-upgrade revalidation.
Support model. No commercial support, no issue-triage SLAs, no security disclosure process. For an internal admin tool with a small, known operator population, that is tolerable. It would not be tolerable for anything customer-facing or in a regulated path — and this package should not be deployed there.
Scaling characteristics. The field itself scales fine; the concern is query behavior it inherits. MorphTo cannot be eager-loaded in a single query — each morph type is a separate whereIn on the Nova index, so a 50-row index across two types costs three queries. That is acceptable on a form or detail view and progressively worse on wide indexes with many morph types. Mitigation is architectural rather than code-level: keep the field off index views and off high-cardinality resources. Inline search also runs through Model::query(), which silently applies global scopes — tenant and soft-delete scopes can make a valid parent invisible and present as a defect. Test the flow under a non-default tenant before general rollout.
Failure modes to instrument for. In practice this field fails in a small number of recognizable ways, and the TPM should know them so triage doesn't stall:
All four surface in the network tab in under a minute, which is why an operator-facing runbook entry plus a middleware log scoped to the relevant /nova-api/* routes is worth more than a monitoring stack for a tool this size.
Ramp-up. Near zero for developers — a field reference and a composer require. The real ramp-up cost is on whoever owns the fork: they need enough Nova familiarity to touch a Vue component and a field class. That person should be named before adoption, not after. Operator ramp-up is likewise minimal; the whole point is fewer steps, so if the pilot requires user training, the value proposition is already in question.
Success criteria and exit. Define these up front: a measurable reduction in time-to-complete for the target admin workflow, no authorization gaps in test coverage, and no unplanned maintenance load in the first quarter. If the workflow improvement isn't demonstrable in a time-boxed pilot, exit — the fallback is a narrow in-house field, and the morph-map and test work done during the pilot carries over to it intact.
How can I help you explore Laravel packages today?