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

Laravel Eloquent Metable Laravel Package

elhareth/laravel-eloquent-metable

elhareth/laravel-eloquent-metable adds flexible key-value metadata to any Eloquent model via a simple trait, letting you attach custom attributes without extra migrations or schema changes.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. laravel-eloquent-metable is a lightweight, trait-based extension that attaches arbitrary key/value metadata to Eloquent models via a polymorphic relationship. It fits the standard Laravel idiom (trait + published migration + relationship), so it slots into a conventional Laravel service-layer architecture without introducing a new abstraction or runtime dependency beyond Eloquent itself. It is complementary to — not a replacement for — JSON columns, Spatie's schemaless-attributes, or a dedicated EAV design. Fit is strongest where metadata is sparse, heterogeneous across records, and read-mostly.

Integration feasibility. Low-to-moderate effort. Typical adoption is composer require, publish and run the migration, then add the trait to each model requiring metadata. Two integration details drive the real cost:

  1. Identifier type alignment. v1.0.0 explicitly adds ULID support (PR #1). If the host application uses HasUlids (or UUIDs) on parent models, the package's polymorphic *_id column must be a string/ULID-compatible type rather than bigint. This is the single highest-value item in the release and must be verified against the published migration stub before rollout.
  2. Mixed-identifier estates. Applications with a mix of auto-increment and ULID models need either a compatible column type across the board or per-table handling; confirm the package supports this without a custom migration fork.

Technical risk. Moderate, concentrated in three areas:

  • Thin release evidence. The v1.0.0 notes are two PR titles ("Add ULID", "updates | enhancements") with no changelog detail on schema changes, no deprecation notices, and no documented breaking changes from 0.x. The jump to 1.0.0 implies a stable public API but does not itself prove one. Treat the API surface as unvalidated until reviewed against source.
  • Single-maintainer bus factor. Both PRs and the release are from @elhareth, who is also listed as a first-time contributor. There is no visible second reviewer or co-maintainer.
  • Query characteristics. Key/value storage invites N+1 access patterns and read amplification. Correct indexing on (metaable_type, metaable_id, key) and disciplined eager loading are prerequisites, not optimizations.

Key questions.

  • Did the published migration change column types for metaable_id, and is that change backward compatible with existing bigint-keyed tables?
  • What precisely is covered by "updates | enhancements" in PR #2 — type casting, query scopes, caching, or fixes?
  • Are values stored as strings only, or is casting/JSON serialization supported? This determines whether consumers can store structured payloads.
  • Does the package register model event hooks to clean up orphaned meta rows on parent deletion?
  • Is there CI, a test suite, and coverage for the ULID path specifically?
  • What is the support policy for Laravel/PHP version ranges, and is it declared in composer.json?

Integration Approach

Stack fit. Designed for Laravel with Eloquent; assumes a relational database. No queue, cache, or external service dependency. Works alongside existing model concerns and does not require changes to controllers or resources beyond exposing/validating meta on write paths. It should be treated as an infrastructure concern owned by the platform team, not a feature-level dependency.

Migration path. Two distinct migrations to plan:

  1. 0.x → 1.0.0. Assume minor breaking changes may exist given the vague notes. Run the package's test suite against a branch, diff the published migration stub against the one already deployed, and gate the upgrade behind a feature branch. Do not upgrade in place on production without a rollback-tested migration.
  2. Bigint → ULID parents. If adopting ULID-keyed models, add new ULID-backed models against the v1.0.0 schema rather than retrofitting existing tables. Retrofitting requires a data migration on the meta table itself and should be scoped as a separate ticket.

Compatibility. Verify declared support for the current Laravel and PHP versions in composer.json before committing. Confirm behavior on the target database driver (MySQL/PostgreSQL/SQLite) — particularly index length limits on metaable_type and collation behavior for key lookups. If the application already uses JSON columns for metadata, do not run both patterns on the same model; pick one per aggregate to avoid ambiguous read paths.

Sequencing.

  1. Spike: install in a sandbox, publish migration, inspect schema and trait source (1–2 days).
  2. Validate ULID path against a representative model with HasUlids.
  3. Add index strategy and confirm query plans for the primary read pattern.
  4. Pilot on one low-risk, read-heavy model with a bounded metadata schema.
  5. Document the allowed key namespace and value types; enforce at the application layer.
  6. Roll out model by model, with a documented escape hatch to a JSON column if the pattern degrades.

Operational Impact

Maintenance. Low code surface but non-trivial ownership. The package is small and single-maintainer; budget for the possibility of vendoring or forking if upstream stalls. Pin the version explicitly in composer.json (avoid floating constraints) and require a review of the diff on each upgrade rather than auto-merging Dependabot PRs — the 1.0.0 notes demonstrate that upstream changelogs cannot be relied on for change classification.

Support. Support burden shifts to the internal team: the allowed metadata keys, their types, and their consumers become an internal contract that must be documented and governed. Without a key registry, metadata devolves into an unowned schemaless dumping ground that no one can safely remove. Assign an owner and a documented key namespace per domain.

Scaling. Performance is dominated by access pattern, not by the package. Requirements:

  • Composite index on (metaable_type, metaable_id, key); verify with EXPLAIN on the top three queries.
  • Mandatory eager loading (with('meta')) in list endpoints; treat lazy meta access in a loop as a defect.
  • Consider a cached meta map per request for hot models.
  • Watch meta table row growth; it grows monotonically with parent count × key count and is not naturally bounded.

Failure modes.

  • Silent type mismatch — bigint column with ULID parents, producing truncated or zero IDs and cross-model meta bleed. Highest severity; validate on day one.
  • N+1 explosion — unindexed or lazily loaded meta degrading list endpoints under load.
  • Orphaned rows — parent deletion without meta cleanup, causing table bloat and stale reads if IDs are reused.
  • Unvalidated writes — arbitrary keys/values accepted, leading to inconsistent types across rows and runtime casting failures in consumers.
  • Schema drift — a package upgrade altering the migration after it has already been applied, leaving environments inconsistent.
  • Upstream abandonment — no security or compatibility patches; mitigated by pinning and a fork contingency.

Ramp-up. Developer ramp-up is genuinely low: a mid-level Laravel engineer can be productive in under a day, and the trait is self-evident to anyone who has used polymorphic relations. The real ramp-up cost is organizational — establishing and communicating the metadata key contract, the eager-loading convention, and the "when to use meta vs. a real column" decision rule. Codify that rule early: if a field is queried, sorted, or validated as first-class, it belongs in a column, not in meta.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib