- What is taldres/laravel-immutable-attributes used for?
- It lets you declare Eloquent model attributes as write-once by annotating them with #[Immutable] and adding the package trait to the model. Once a row exists, any save that would alter those attributes throws, which helps protect invoice numbers, external or ledger IDs, tenant ownership at creation, audit identifiers, and similar lifecycle invariants. It is an application-layer guardrail for Eloquent saves, not a database constraint.
- How do I install and configure laravel-immutable-attributes?
- Install it with composer require taldres/laravel-immutable-attributes, add the package trait to each Eloquent model you want to protect, and annotate the relevant properties with #[Immutable]. The package is described as requiring no service provider configuration or migration, so setup is mostly per model. Confirm the exact trait namespace and attribute import from the README before rolling it out.
- Which Laravel and PHP versions does laravel-immutable-attributes support?
- The package targets modern Laravel on PHP 8.1 or newer, with an expected fit for Laravel 9 through 12, because PHP attributes require PHP 8. You should verify the composer.json constraints and CI matrix before adoption, since the available assessment does not confirm the tested version range. Run your own smoke test on the exact Laravel version your application uses.
- Does laravel-immutable-attributes prevent bulk updates and upsert?
- No. It guards Eloquent model saves, so query-builder bulk operations such as Model::where(...)->update(), insert(), upsert(), DB::table(), raw SQL, and writes from other services or replicas can bypass it. Test saveQuietly() and Model::withoutEvents() as well, because whether the guard fires depends on whether the package uses a saving override or an event listener.
- What exception does #[Immutable] throw when an attribute changes?
- The exact exception class is not identified in the package overview or technical assessment, so inspect the source and README before mapping it to an HTTP response. You want a namespaced, distinguishable exception so you can catch it and return a 409 Conflict or 422 validation error instead of a generic 500. If it throws a generic exception, catch it at the boundary or add your own domain check around the save.
- Is there an observe or log-only mode for immutable attributes?
- No observe or log-only mode is mentioned, so the guard appears to be an unconditional throw when a protected attribute changes. A staged rollout that logs violations before enforcing them would likely require a local fork or a wrapper around the save call. If you need audit telemetry, plan to add it yourself rather than expecting it from the package.
- How does it handle casts like encrypted, JSON, decimal, and dates?
- Be careful with casted attributes because Eloquent uses originalIsEquivalent() and loose comparison when deciding whether a value changed. Decimal or float precision, Carbon date mutation in place, JSON key ordering, and encrypted casts can cause false positives or let a real change slip through. Add test cases for every immutable attribute using its real cast before enforcing this in production.
- Can I use it on columns like updated_at, deleted_at, or status?
- Do not annotate columns that legitimately change after creation, including updated_at, deleted_at for soft deletes, state-machine status, or tenant reassignment. The package is intended for true write-once values such as invoice numbers, ledger IDs, and audit-relevant identifiers. A misapplied attribute can pass tests and then fail in production when a normal lifecycle update throws.
- How should I test immutable attributes in Laravel?
- Write feature tests that create the model, change each immutable attribute, and assert the expected exception on save. Add bypass tests for bulk update(), upsert(), saveQuietly(), and Model::withoutEvents() so you understand your real coverage. Include cast-specific cases for dates, decimals, JSON, and encrypted values, plus firstOrCreate and updateOrCreate flows.
- Is taldres/laravel-immutable-attributes maintained and safe to depend on?
- The package has very low adoption, a single maintainer, and a supply-chain profile where abandonment should be the base case. The listed release date is also future-dated, which suggests a feed or tagging issue, so verify actual tags, CI status, and test coverage on the repository. For critical invariants, consider borrowing the design or adding a database-layer constraint alongside the package.