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 Belongs To Dependency Laravel Package

manmohanjit/nova-belongs-to-dependency

A Laravel Nova field package that makes BelongsTo relationships depend on another form field. When the parent select changes, the dependent BelongsTo options reload and filter automatically, enabling cascading dropdowns such as country, state, and city inside Nova resources.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package like any Nova tool/field package and confirm asset registration before touching your resources:

composer require manmohanjit/nova-belongs-to-dependency
php artisan nova:publish   # or: vendor:publish --tag=nova-belongs-to-dependency

Where to look first:

  1. vendor/manmohanjit/nova-belongs-to-dependency/README.md — the exact method name for wiring the parent field lives here. Don't guess from the class name; the API is small and the README is the only source of truth.
  2. src/BelongsToDependency.php (or similarly named field class) — check which base class it extends (Laravel\Nova\Fields\BelongsTo), what it adds to relatableQuery/jsonSerialize, and whether it ships a compiled dist/js bundle or source only.
  3. composer.json — check the laravel/nova and php constraints. This tells you instantly whether it targets Nova 3 or Nova 4.

First use case: the classic cascading select — Country → State, Tenant → Team, Category → Subcategory. Drop it on a resource form where a BelongsTo should only list options valid for the sibling field's current value:

use Manmohanjit\BelongsToDependency\BelongsToDependency;

public function fields(Request $request)
{
    return [
        BelongsTo::make('Country'),
        BelongsToDependency::make('State')
            ->dependsOn('country'),   // parent's field attribute, not its label
    ];
}

Then filter the child resource's relatableQuery on the value the field forwards. Start there, verify the options refresh in the browser when you change the parent, and only then wire up a second dependency.

Implementation Patterns

Filter on the child resource, not in the field. The package sends the parent's value along with Nova's relatable request; the actual narrowing is your job on the target resource:

// app/Nova/State.php
public static function relatableQuery(NovaRequest $request, $query)
{
    if ($countryId = $request->input('dependsOn') ?? $request->input('country')) {
        $query->where('country_id', $countryId);
    }
    return $query;
}

Confirm the request key the field actually sends by inspecting the network tab once — the package's JS is what names it.

Pair it with the matching parent field type. The package advertises support for BelongsTo, Text and Status parents, which means "dependency value" can come from a searchable dropdown, a free-text slug, or an enum-backed status. For Text parents, normalize server-side (strtolower, trim) before filtering so the option list stays stable.

Edit vs. create forms. On edit, the parent already has a value, so the child populates immediately. On create, the child is blank until the user picks a parent — make sure the field clears its stale selection when the parent changes, and consider gating submission with ->rules('required') only after the parent is required too.

Multi-level chains. Chain two instances (Country → State → City) by having each dependsOn the previous. Keep the chain shallow — each link is another round-trip on the relatable endpoint, and the component re-fetches on every parent change.

Pair with dependsOn-aware index filters. If the same cascade appears in a Nova filter or lens, reuse the same query logic in a private helper on the child resource so the form and the filter can't drift.

Testing. Feature-test the relatable endpoint directly — it's the real contract:

$this->actingAs($user)
    ->getJson("/nova-api/states?dependsOn=5")
    ->assertOk()
    ->assertJsonCount(3, 'resources');

That test survives a package upgrade or a swap to a hand-rolled field, which is exactly the insurance you want for an archived dependency.

Gotchas and Tips

  • This package is archived. No Laravel 11 / Nova 5 fixes are coming. Pin your laravel/nova constraint and budget a replacement (a small custom BelongsTo with a relatableQuery filter and dependsOn meta passed via withMeta) before your next major Nova upgrade. For a 10-star package, assume you own the code the day you install it.
  • Nova 4's Vue 3 migration breaks prebuilt assets. If the shipped dist/js was built against Nova 3's Vue 2 toolchain, the field may render nothing or throw in the console. Check dist/ first; if there's no source, you cannot rebuild it.
  • Asset publishing is required and easy to miss. A field that "doesn't appear" or "shows a plain input" is almost always an unpublished/mismatched JS bundle. Re-run nova:publish after any composer update that touches the package.
  • Use the field attribute, not the label. ->dependsOn('Country') will silently never match if the attribute is country. Symptoms are an unfiltered dropdown, not an error.
  • Stale options without a clearing step. If changing the parent leaves an old selection in the child, add a ->rules() guard or an saving() check on the model so a now-invalid belongs_to id can't be persisted.
  • Search performance. Nova's searchable BelongsTo queries your relatableQuery with LIKE; adding a where on the dependency without an index on that foreign key turns the dropdown into a table scan on large tables. Index country_id (etc.) before shipping.
  • dependsOn and nullable interact badly on bulk create. If the parent is optional, define explicit behavior for the empty case — usually "show all options" or "show none and disable" — rather than letting the backend return the full unfiltered list.
  • Extension point if you must fork: the clean seam is relatableQuery on your child resource combined with the field's meta payload. You can keep the package's frontend behavior and move all business logic server-side, which is the least painful path to eventually replacing it.
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.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus