- How do I install and set up we-are-neopix/laravel-model-translation?
- Install it with Composer, publish the package config, then add the provided trait to each model you want to translate and declare the attributes in a $translatable property. After that you pick a driver, either the database driver or the JSON file driver, and the package resolves attribute values for the active locale through normal Eloquent accessors. There is no routing, middleware, or Laravel lang file integration to wire up, so the whole change stays confined to the models you opt in.
- Which Laravel and PHP versions does this package support?
- Check the declared laravel/framework and php constraints in the package's composer.json against your pinned LTS and PHP baseline before committing to it. Because it hooks into Eloquent attribute resolution, trait-based packages like this one typically need a patch cycle for each new Laravel major, so budget one to two engineer-days per upgrade. Add a contract test that exercises translated attribute reads in CI so a framework bump fails loudly instead of silently returning wrong values.
- What is the difference between the database driver and the JSON driver?
- The database driver persists translations in a table, which means you own that schema, its indexes, and its growth as models times attributes times locales accumulate. The JSON driver writes translations to files on disk, which is fine for local development but hostile to read-only container filesystems, ephemeral instances, and multi-instance deployments where writes can race or diverge. Many teams adopt the JSON driver as a local convenience only and use the database driver everywhere else.
- How do I make an existing Eloquent model translatable?
- Add the package trait to the model and list the attributes you want translated in the $translatable array. Once declared, reading those attributes returns the value for the current locale rather than the raw stored value, so existing Blade templates and API resources pick up translations without rewrites. Keep the opt-in list narrow, ideally content models such as CMS pages, product catalogs, categories, or help articles, to keep the blast radius small.
- What happens when a translation is missing for the current locale?
- The package can return null, substitute the default locale value, or raise an exception depending on how it is configured, so verify the actual behaviour in your spike rather than assuming. This matters because silent nulls ship blank labels to end users and surface as a product bug rather than a technical one. Make the fallback rule an explicit product decision in your application code instead of inheriting whatever the library defaults to.
- Can I write my own driver to store translations somewhere else?
- Yes, the package is driver based and exposes a contract you can implement for custom storage backends, then register for use with the package. That flexibility is an architectural hedge that lowers the cost of switching storage later, but it does nothing to reduce the cost of the package itself going unmaintained. Weigh the effort carefully, since writing a custom driver converts a dependency you consume into an implementation you own and must test.
- Does this package require extra database tables or schema changes?
- The JSON driver needs no schema changes at all, while the database driver requires a translations table that you will own permanently. Before go-live, confirm the table has a composite unique constraint and a covering index on the lookup tuple, typically model type, model id, attribute, and locale. Without those indexes every translated read degrades toward a table scan, which becomes a long-term runbook and DBA cost rather than a one-off migration.
- How do I avoid N+1 queries when translating many models?
- Translated values are resolved lazily behind normal property reads, so rendering a Blade loop or serializing an API collection can trigger a query per model per attribute. Decide during your spike whether you need eager loading, batch resolution, or a caching layer, because that answer changes the estimate from hours of integration to hours plus a performance workstream. If no batching or eager-loading hook exists, add a cache in front of the accessor before shipping list views.
- How should I test translated attributes in my application?
- Write contract tests that assert a value resolves correctly per locale, that the fallback rule behaves as specified for a missing translation, and that driver resolution picks the driver you configured. Run those tests in CI so a Laravel major upgrade or an out-of-band fork patch is caught immediately. If you implement a custom driver, test it separately against the package contract so storage changes never leak into feature tests.
- Is this package actively maintained, and what are the alternatives?
- Adoption signals are thin, with roughly forty stars, no visible dependents, and a single agency maintainer, so treat sustainability as a known risk rather than a surprise. The mitigation is fork-and-own: the capability is narrow enough that an in-house replacement is on the order of a couple of hundred lines, and well-known alternatives such as spatie/laravel-translatable exist for JSON-column translation if you prefer a larger ecosystem. Whichever route you take, confine the package to a bounded set of content models so an abandonment only touches a handful of models, not a subsystem.