dialloibrahima/laravel-model-media
A Laravel package for attaching media files to Eloquent models. Upload, store, and associate images or documents with your records through a simple, fluent API, keeping media handling clean and organized. Ideal for galleries, avatars, and file attachments.
Architecture fit. This package occupies a deliberately narrow architectural slot: a trait that stores a media reference as a plain Eloquent attribute, with no media table, no polymorphic pivot, and (presumably) no service-provider migrations. That is a genuine fit for three cases: (1) brownfield schemas that already carry avatar_path / attachment columns and cannot absorb a new table, (2) read-heavy models where avoiding a join per render is worth more than rich metadata, and (3) small monoliths and internal tools where the full spatie/laravel-medialibrary footprint (media table, conversions, queue-driven image pipeline) is disproportionate. It is a poor fit for multi-tenant SaaS with shared asset reuse, per-file audit trails, image variant generation, or a requirement to attach N files per model — those needs push you back toward a dedicated media table almost immediately, and the trait will not grow into them.
Integration feasibility. Low effort, measured in hours. Expected shape: composer require, use the trait on a model, configure a disk/path convention, and call accessors/upload helpers. The real feasibility work is verification, not implementation: Laravel and PHP version constraints in composer.json, whether disk access goes through the Storage facade or hardcodes a public path, whether it hooks deleting/forceDeleting to unlink files, whether it handles file replacement atomically, and whether URL generation is CDN/proxy-aware. Zero dependents means no third-party validation of these behaviors in the wild — we verify them ourselves in a spike.
Technical risk. Ranked:
Key questions for the maintainer / spike. Does it use Storage/Illuminate\Filesystem\FilesystemAdapter exclusively? Which Laravel and PHP majors are in the CI matrix? Are file deletions wired to model events, and does that include forceDelete? How are filename collisions resolved? Does it support multiple attributes per model and multiple disks per attribute? Is there a fallback/placeholder mechanism when the file is missing? Is upload handling in scope, or purely path management? What is the test coverage and is there a tagged release cadence?
Stack fit. Laravel with the standard Storage abstraction (local and S3-compatible disks), PHP 8.x per the package's constraints. No queue or worker dependency, no migration step, no cache or search component. It sits equally well under Blade, Livewire, or Inertia front ends because it only produces paths/URLs.
Migration path. Two distinct paths, and we should pick per-surface rather than uniformly:
AttachesMedia) and a thin adapter that delegates to the trait today and to spatie/laravel-medialibrary (or an in-house table) later. The trait becomes an implementation detail, not an architectural commitment. This is the single highest-leverage decision in the whole assessment, and it costs ~a day.For brownfield adoption, map existing path columns first; do not introduce new columns beyond what the trait requires, and do not backfill until the spike confirms read behavior against real data.
Compatibility. Confirm composer.json constraints against our Laravel major and PHP minor before anything else — this is the most common hard blocker for low-adoption packages. Check for attribute-name collisions with existing casts/accessors, and confirm the trait composes cleanly with SoftDeletes, HasFactory, and any existing HasMedia-style traits on the same model. Verify behavior on read-only filesystems and under Storage::fake() so tests are hermetic.
Sequencing.
composer.json; no floating constraint on a single-maintainer package.Maintenance. Steady-state cost is low — no migrations to run, no schema to evolve, essentially one dependency line. The burden is anticipatory: a quarterly composer audit, active watching for Laravel major releases, and a standing decision about fork-and-vendor. Given the single-maintainer risk and small code surface, mirroring the repo into private VCS or vendoring the trait is cheap insurance and should be decided at adoption time, not after an incident.
Support. No vendor, no SLA, GitHub issues only. An internal owner must be named explicitly; otherwise this becomes nobody's dependency until it breaks during a framework upgrade. Documentation depth is unknown — budget for reading the trait source rather than trusting the README.
Scaling. Runtime cost is effectively zero and is the package's core advantage: no extra query, no join, no eager-load requirement on list pages. Scaling pressure shifts entirely to storage hygiene — no deduplication of identical uploads, no generated variants (so originals may be served at full size unless we add a transform layer), and no automatic orphan reclamation. Past a few hundred thousand files, plan a scheduled reconciliation job comparing filesystem listings against referenced paths.
Failure modes to instrument.
Ramp-up. Hours for a mid-level Laravel developer; the API surface is a trait plus a handful of methods. The onboarding risk is not learning the package, it's not learning the package: developers will assume it does what Spatie does. Document explicitly what it does not do — no variants, no metadata, no audit trail, no dedupe — so the constraint is visible before someone builds on an assumption the package can't support.
How can I help you explore Laravel packages today?