igrik/nova-inline-relationship
A Laravel Nova field for managing has-one and belongs-to relationships inline: search, create, and link related records directly from the parent form without leaving the page. A simple drop-in alternative to Nova's default relationship fields.
This is a small, low-adoption package (0 stars, 0 dependents) that gives you an InlineRelationship field for Nova resources. It flattens a related model’s attributes into the parent resource’s index/detail views so you don’t have to click into a related resource just to read a couple of columns. Treat it as a display convenience, not a full relationship-field replacement.
Minimal steps:
composer require igrik/nova-inline-relationship
composer.json for a providers/aliases block.composer why-not laravel/nova after install to confirm it didn’t force anything.vendor/igrik/nova-inline-relationship/src/ and read the InlineRelationship class. With a package this small and undocumented, the source is the documentation — confirm the field API (fields(), make() argument order, supported relationship types) before writing resource code.BelongsTo/HasOne you display on the index — e.g. an Order resource showing the customer’s name and email without an extra resource click.use Igrik\NovaInlineRelationship\InlineRelationship;
public function fields(Request $request)
{
return [
InlineRelationship::make('Customer')
->fields([
Text::make('Name', 'name'),
Text::make('Email', 'email'),
]),
];
}
Display-only on index/detail (recommended).
Use the field where you need read access to related attributes. Keep the relationship declared normally on the model (customer()), and eager load it in indexQuery/detailQuery to avoid N+1.
public static function indexQuery(NovaRequest $request, $query)
{
return $query->with('customer');
}
Mirroring a related resource’s fields.
Define the inline fields to match the related resource’s fields(), but keep them minimal — just what belongs on the parent screen. Don’t drag in every related field; that’s what the relationship link is for.
Panels/groups for readability.
Wrap the inline field in the same layout primitives you use elsewhere (Panels\Panel, Field::make(...)->rules(...) grouping) so visually it doesn’t look like a floating block of unrelated fields.
Guarding against missing relations.
Related records can be null. If the package doesn’t handle it gracefully, resolve defensively in the field setup (e.g. ->hideIf(...) or a resolveUsing/displayUsing callback) so an empty relation doesn’t blow up the index.
Form usage — be conservative. If the field supports writing back through the relationship, test it hard: create, update, validation failure, and partial payloads. If it’s display-only in practice, pair it with the normal Nova relationship field for editing so you don’t end up with an unvalidated side-channel writing to a related model.
Migration note. Nova 4+ has native tooling for this kind of flattening (relationship fields, computed fields, BelongsTo display callbacks). If you’re on Nova 4, consider BelongsTo::make(...)->displayUsing(...) or a computed field first and only reach for this package if it saves meaningful boilerplate.
indexQuery, an index of 50 rows becomes 50+ queries. Always check with DB::listen or Telescope.sortable() and filters won’t work unless the package explicitly joins them (unlikely for a package this size). Don’t expose them as sortable headers.BelongsTo, HasOne, MorphOne) to work; HasMany/BelongsToMany/MorphMany are usually not rendered as inline cells. Verify in the source before designing a screen around it.composer.json and add an integration smoke test (index + detail + form) so a Nova upgrade doesn’t silently break rendering.(new YourResource)->fields(request())) to see what attributes the field actually asks for, and inspect the compiled Vue assets in dist/ if the front-end rendering looks wrong — a stale dist is a common cause.Field subclass, so resolveUsing, displayUsing, onlyOnIndex/onlyOnDetail, canSee, and hideWhenUpdating all apply normally. Use them to scope the field to read contexts.authorizedToView policies. If the related data is sensitive, gate the inline field itself with canSee and a policy check.How can I help you explore Laravel packages today?