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 Two Way Attribute Casting Laravel Package

genealabs/laravel-two-way-attribute-casting

A Laravel package that enables two-way attribute casting on Eloquent models, letting you transform values both when reading from and writing to the database with custom cast classes. Useful for encapsulating conversion logic in one place for cleaner, reusable model code.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

The decision this assessment actually unlocks is a "no-build, no-buy" call — and that is a useful output. The underlying problem is real and worth framing for the roadmap: monetary and precision-sensitive attributes (decimal(10,2) columns) are frequently passed through PHP floats, and that round trip is a recurring source of "off by one cent" defects in pricing, invoicing, tax, and reporting surfaces. What this specific package changes is whether we solve that with a third-party dependency or with the framework.

  • Build vs. buy, resolved in favor of the framework. Laravel 7 (March 2020) shipped native custom casts via CastsAttributes::get() / set(), which apply on both hydrate and persist — precisely the "two-way" behavior this package advertises. Laravel 10/11 add the casts() method and CastsInboundAttributes. This package's last release is May 2018, predating that API, and the repo is archived with 1 star and 0 dependents. The capability is now a framework primitive, so the buy decision collapses to zero cost: write a small in-house cast class.
  • Roadmap sequencing for money-adjacent features. Checkout, subscriptions, payouts, and ledger reporting all benefit from a consistent cast contract at the model boundary. That is a legitimate roadmap item — but it should be scoped as "standardize decimal handling in Eloquent," not "adopt this package."
  • Risk sizing for the quarter. This is an archived, pre-1.0, eight-year-old dependency with no maintainer and no security response path. That is not a pilot candidate; it is a supply-chain liability. Sizing it correctly as "do not adopt" frees the effort for the native implementation, which is roughly half a sprint.
  • Legacy inventory decision. If any codebase already has hand-rolled (float) casts, string-formatting accessors, or a vendored copy of this package, this assessment supports a migration ticket: replace with CastsAttributes implementations, delete the accessors (they override casts and cause silent drift), and add round-trip tests.
  • Prioritizing the defect class. If support tickets or reconciliation work trace to monetary precision, that is evidence to schedule the standardization work now rather than after the next pricing feature — independent of this package.

Net PM framing: the problem is worth funding; this package is not the vehicle.

When to Consider This Package

Adoption criteria (all would have to be true):

  • The application is pinned to a Laravel version that genuinely lacks native two-way custom casts (roughly 5.x–6.x, i.e. pre-March 2020), and an upgrade is blocked by a dependency you do not control.
  • The package has been vendored into the repo or mirrored to a private registry, because the upstream repo is archived and Composer installs depend on a dead source.
  • You have written and can own the round-trip test suite yourself — there is no upstream test plan to inherit, no maintainer to file against, and no upgrade path.
  • The exact version is pinned (^0.1.2, not floating), since 0.1.2 changed decimal hydration behavior and 0.1.x semantics were never frozen.
  • You accept that the documented "works with Eloquent custom cast classes" claim is the package's own framing and predates the framework API it describes — treat the source, not the docs, as the contract.

Realistically, that combination means: do not adopt for new work, and treat any existing usage as tech debt with a remediation ticket.

Look elsewhere when (the common case):

  • Laravel 7+ — use a native CastsAttributes class. You get two-way casting, an upgrade path, and no dependency. This covers essentially all modern applications and should be the default recommendation.
  • Currency-aware arithmetic, conversion, allocation, or locale formatting — use moneyphp/money (with brick/math for arbitrary precision) and let the cast handle persistence only. A cast normalizes representation; it does not make operators safe, handle FX, or format for a locale.
  • Regulated financial reporting or audit-critical ledgers — you need pinned behavior, documented rounding semantics, and your own regression suite. An abandoned 0.1.x package cannot supply the change-control story an auditor will ask for.
  • Aggregate-heavy reporting — note that ->sum('amount') bypasses casts entirely and returns whatever the driver hands back (a string on MySQL, sometimes an integer on SQLite). No cast package solves this; budget for explicit re-wrapping at the query layer.
  • Cross-driver portability requirements — MySQL and SQLite differ in what they return for the same decimal column. If CI and production use different drivers, that must be tested directly; the package's one historical bug fix (decimal handling in 0.1.2) is a marker of exactly this class of edge case, not evidence it is exhausted.
  • You need maintained support — archived status means no security patches, no Laravel 12 compatibility work, and no one to escalate to. That alone disqualifies it from production dependency lists in most organizations.

How to Pitch It (Stakeholders)

For executives: We evaluated a small open-source Laravel component that standardized how precise decimal values — prices, totals, tax — are read from and written to the database, with the goal of reducing cent-level rounding errors that surface as customer-facing discrepancies and reconciliation work. Recommendation: do not adopt it. The project has been archived by its maintainer, has no users, and last shipped in 2018; more importantly, the framework itself now provides the same capability natively, so there is nothing to license, procure, or maintain. The business need is still real and worth one bounded piece of work: standardize decimal handling in our Eloquent models using Laravel's built-in casting, cover it with round-trip tests, and close the defect class. Cost is internal effort only — roughly half a sprint — with no dependency, no lock-in, and no vendor risk. If any codebase already depends on this package or its hand-rolled equivalent, that becomes a small, scheduled cleanup rather than an open question.

For engineering: The package predates Laravel 7's CastsAttributes interface and is now redundant — the framework applies get() and set() symmetrically on hydrate and persist, which is the entire value proposition described. Last release May 2018, repo archived, zero dependents, one historical fix (0.1.2, decimal handling). Recommendation: close the spike; implement a small in-house cast.

The work, if we proceed:

  1. Replace float-mediated reads/writes on decimal attributes with a native CastsAttributes implementation (or a thin wrapper around moneyphp/money if currency semantics enter scope — do not extend the cast to cover FX or locale formatting).
  2. Keep the schema honest: migration decimal(10,2), cast scale parameter, and validation rule (decimal:0,2) must agree. Mismatch here is the top source of silent truncation.
  3. Normalize at the boundary — canonical strings in prepareForValidation, never floats on assignment — and do arithmetic outside the model (bcmath or the value object's methods).
  4. Remove any pre-existing accessor or Attribute mutator on the same attribute; it wins over the cast and reintroduces drift.
  5. Test with assertSame on normalized strings, one case per write path (create, update, fill, refresh, first) plus negative, zero, and high-scale values; run against both the CI driver and the production driver.

Guardrails: decide and document rounding vs. truncation for over-scale input (19.999 → 19.99 or 20.00), pin a canonical output scale so string equality and cache keys are stable, and confirm whether null is preserved or coerced to 0.00 — that distinction affects whereNull queries and form prefill. Keep the cast behind a consistent attribute contract so a future swap to moneyphp/money stays cheap.

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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator