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

Many To Many Laravel Package

armincms/many-to-many

A Laravel package that extends Eloquent many-to-many relationships with helpers for attaching, detaching, and managing related models through pivot tables. It aims to simplify common relationship workflows and offer a cleaner API for complex many-to-many handling.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is a Laravel Nova field, not a general-purpose Eloquent helper. Its architecture is strictly bounded: it drops into a Nova resource's fields() method and renders a searchable multi-select transfer UI that maps to an existing BelongsToMany relationship. That means it inherits Nova's architecture wholesale — Vue front-end components registered globally through a service provider, a PHP field class extending Nova's field base, and published compiled assets. The fit is good if and only if the product is already on Nova. If Nova is absent, or the intended consumer is a customer-facing surface, the package is inert and should be dismissed immediately.

Integration feasibility. Feasible at low cost as a pilot. The delta versus Nova's native BelongsToMany field is what matters: richer inline pivot editing, on-the-fly creation of related records, configurable labels/search, and a searchable multi-select. If those features are already covered by native Nova or by an existing field package in the stack, the business case collapses. The real integration friction is not PHP — it is the dual declaration of pivot data: UI fields must be mirrored in the Eloquent relationship's withPivot(), or values fail to persist silently. That is a correctness trap, not a build trap, and it argues for a round-trip test before trusting the field anywhere.

Technical risk. The dominant risk is Nova 5 compatibility: the last release is February 2023, which places it in the Nova 4 era, and Nova 3 → 4 → 5 changed front-end internals materially. Front-end failures here present visually, not in logs — the field renders blank and nothing appears in storage/logs/laravel.log. Secondary risks: 25 stars, 0 dependents, single maintainer, no commercial backing, so assume you may own a fork; a hard Composer constraint could block a Nova upgrade across the entire admin panel, not just the resources using the field; possible global Vue component-name collisions with other installed Nova field packages; unverified morph (morphToMany) support; and unknown handling of large related-record sets where selector degradation is a render-latency problem, not a database-cost problem.

Key questions for the spike (time-boxed, roughly one engineer-day).

  • What are the laravel/nova, laravel/framework, and php constraints in composer.json, and do they match our stack?
  • Is a compiled Vue bundle committed in dist/, or do we need an internal npm run build step in CI?
  • What fluent methods and extension points actually exist in src/ — do not assume BelongsToMany parity?
  • Does it eager-load pivot attributes, or will we need a resource-level mitigation?
  • Is server-side search and pagination present, and how does it behave at production-scale record counts (thousands, not ten fixtures)?
  • Does it support morphToMany, or do we need a custom field?
  • Is there any test coverage, and does a pivot column round-trip in a fresh install?

Integration Approach

Stack fit. Pinned Nova field on a single low-risk resource. Nova 4-era stack, conventional pivot-table modeling, simple pivot columns (order, weight, assigned-at, a role label). Explicit non-fits: audit trails, approvals, bulk operations, import/export, granular permissions, membership history. Tagging is the correct first use case; roles/permissions are the wrong first use case because detaching the wrong record has authorization consequences.

Migration path. Additive and reversible by design. Define the Eloquent relationship first — it is the contract, the field is only the UI. Then register the field on the resource and keep the native field as a documented one-line fallback:

// Native Nova
BelongsToMany::make('Tags')
// vs.
ManyToMany::make('Tags')   // attribute name must match the relation method

Rollback is a field swap, which is exactly why this is a cheap experiment to authorize. Adopt field-by-field at the resource level, never globally, and record in the repo which resources use which field — otherwise the first team rotation loses that knowledge.

Compatibility. Test three axes independently rather than inferring from the release date: Nova major version, Laravel/PHP version, and Vue 2 vs Vue 3 toolchain. Pin exactly, not with a caret:

"armincms/many-to-many": "1.0.0"

A hard conflict here is panel-wide, so treat the pin as a blast-radius control, not a hygiene habit. Confirm the field's FQCN and service provider against src/ before wiring it up.

Sequencing.

  1. Spike (½–1 day). Install on a throwaway branch, pinned. Read composer.json, src/, and dist/. Verify the delta versus native Nova is real and valuable.
  2. Pilot (one sprint). One internal resource, simple pivot, with withPivot() mirroring the UI fields and a test asserting a pivot column round-trips.
  3. Validate deploy in a clean CI container. Publish assets in the build step, idempotently; missing publish steps surface in fresh containers, not warm local machines:
    php artisan vendor:publish --provider="Arminecms\ManyToMany\ManyToManyServiceProvider" --tag=assets --force
    
  4. Smoke test. Open the form, attach, set a pivot value, save, reload. Blank field almost always means an asset/component mismatch, not a PHP error.
  5. Promote, or exit. Promotion requires a named owner, a recorded fork point (commit SHA), and a line in the Nova-upgrade checklist. Pre-agree the exit criteria before the pilot starts.

Operational Impact

Maintenance. The real cost is ongoing ownership, not the install. Budget for an internal owner of Nova-upgrade triage from day one, and assume you may fork — MIT makes the fork clean legally, but the price is maintaining a small PHP + Vue component indefinitely. Keep a written record: resources using the field, the native fallback, the pinned version, the fork location, and the Nova-upgrade checklist entry. Without that artifact this becomes silent technical debt at the next team rotation.

Support. Effectively none. Single maintainer, no commercial backing, no release since Feb 2023, thin community signal. Escalation path is the source code, not the docs — the README is a paragraph and the documentation is thin. Plan engineering time to read src/ rather than expecting vendor answers.

Scaling. Two distinct ceilings. Vertically, the selector degrades on large related-record sets: without server-side search and pagination, thousands of tags will produce a slow, unusable form — a front-end problem, not a database-cost problem, so it will not show up in query profiling. Horizontally, admin-panel concurrency is rarely a concern; the risk is breadth of adoption, since a Composer constraint conflict blocks a Nova upgrade across the whole panel, not just the resources using the field.

Failure modes to instrument for.

  • Blank field after a Nova minor upgrade — the classic mode. Visual, unlogged. Mitigation: add "open the Post edit form" to the Nova-upgrade checklist, plus an optional Dusk/Nova browser test on the pilot resource.
  • Silent pivot persistence failure — UI column absent from withPivot(). Mitigation: round-trip test asserting the pivot column saves on create and update (watch sync() vs syncWithPivotValues() behavior).
  • Wrong component rendering — global Vue component-name collision with another installed field package. Mitigation: confirm the registered name in the service provider before assuming the field is broken.
  • Detach ≠ soft delete. The field deletes pivot rows. If relationship history carries business meaning (memberships, assignments), that is a pivot model with SoftDeletes and a different UI — discover it in design, not after launch.
  • Title resolution blanks. No $title or a missing name/title yields IDs or empty labels. Set public static $title and $search on the related resource explicitly.
  • Debug order for a blank field: published dist/ assets → browser console for a missing Vue component → field registered in fields() with a name matching the relation method → composer show matches the pin.

Ramp-up. Low for engineers already fluent in Nova resource work — a familiar fluent field API on a resource they already own, and the concepts (relationship as contract, withPivot() as whitelist) are native Eloquent. Non-trivial for anyone debugging the front-end half, because failures are silent and the Vue bundle is opaque. Keep the field inside fields(); for bulk attach/detach write a Nova Action rather than extending the field — mixing responsibilities is how a small UI dependency becomes a fork you maintain full-time.

Recommendation. Conditional pilot only where the spike proves a specific, valuable capability gap over native Nova BelongsToMany. Default position remains native. The ask is roughly one engineer-day plus a one-sprint pilot on one internal resource, with pre-agreed exit criteria: no hard Composer conflict, assets publish cleanly in CI, pivot columns round-trip, and acceptable performance at production-scale record counts.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console