morontt/doctrine-to-ember
morontt/doctrine-to-ember bridges Doctrine and Ember.js by generating Ember Data models from your Doctrine entity metadata, keeping frontend and backend schemas in sync and reducing manual model duplication.
Reality check before you composer require anything. This is a Symfony bundle, not a Laravel package — its repo name is DoctrineToEmberBundle, it registers via AppKernel, and it operates on Doctrine ORM metadata, neither of which exists in a Laravel app. It is also archived, has 3 stars, 0 dependents, and its last activity predates modern Symfony/Laravel. Your day-to-day leverage on it is essentially zero as a runtime dependency; its value is as a reference implementation for a code generator you will likely write yourself.
Minimal steps if you insist on evaluating it directly (Symfony side, e.g. a legacy app you're maintaining):
composer require morontt/doctrine-to-ember — expect constraint friction; the package targets Symfony 2/3-era symfony/framework-bundle and Doctrine 2.x.app/AppKernel.php (there is no auto-discovery under Laravel, and no AppKernel either).belongsTo/hasMany-relevant association mappings — the generator reads mapping metadata, not the database schema.Command/ directory (the README is the only authoritative source for the command name and its arguments) and run it with an output path pointing at your Ember app's app/models/ directory.Where to look first in the source, in this order: the Command/ class (arguments, options, output path), the DependencyInjection/ extension (config keys, type-mapping services), then the template/generator service (how Doctrine field types become Ember transforms).
First real use case: you have a JSON API (Ember Data consuming it) backed by a Doctrine app, and you want the app/models/*.js scaffolding generated rather than hand-typed, so relationship names and DS.attr types stay in sync with the entities.
The Laravel translation of that first use case — and the only version of this you'll actually ship — is an artisan command:
// php artisan make:command EmberModels --command=ember:models
// Read schema via Schema::getColumns()/getIndexes() or model reflection,
// then write app/models/{dasherized}.ts with DS.attr / @belongsTo / @hasMany.
Use the bundle's generator as the spec for naming, type mapping, and relationship pruning; implement the I/O against Laravel's schema builder or Eloquent metadata.
Treat it as a one-shot scaffolder, not a runtime dependency. Nothing here belongs in require rather than require-dev, and even there it will fight Laravel's own symfony/* v6/v7 constraints.
Patterns worth copying into your own generator:
Type mapping table. Doctrine string/text → DS.attr('string'), integer/bigint/float/decimal → DS.attr('number'), datetime → DS.attr('date'), boolean → DS.attr('boolean'). Keep this as a config array you can override per project — the bundle's DI extension is the model for that hook.
Relationship derivation from mapping, not from FKs. belongsTo/hasMany should come from association metadata (owning vs. inverse side), because a foreign key column alone doesn't tell you the cardinality you want in Ember. In Laravel, this means reading $model->belongsTo() / hasMany() relations reflectively rather than inferring from Schema.
Generate into a checked-in directory and diff in CI. This is the single most valuable workflow:
php artisan ember:models
git diff --exit-code app/models/ || (echo "Generated Ember models are stale"; exit 1)
It converts "silent drift between backend and frontend" into a failed build.
Scope the generator. Whitelist the entities/models you actually expose. Generating models for users, password_resets, jobs, failed_jobs, personal_access_tokens is noise at best and an information leak in your frontend bundle at worst.
Naming pipeline. Table/class → dasherized Ember model name; snake_case columns → camelCase attributes; plural table names → singular model names. Fix the convention once in a config file and test it — Ember's dasherize/pluralize will disagree with your assumptions on irregular nouns.
Pair with a serializer contract. Ember Data is pickiest about the payload, not the model file. If you're bridging to Laravel, standardize on JSON:API (laravel-json-api or hand-rolled JsonResource with type/id/attributes/relationships) so the generated models' @belongsTo/@hasMany names match keys on the wire. Generated models against an ad-hoc REST payload is where people burn days.
Customize in Ember, not in generated output. Any per-model behavior (computed properties, custom serializers, async: false) goes in an app/models/foo.js reopen, a mixin, or app/serializers/foo.js — never in the generated file, which will be clobbered on the next run.
symfony/* v6/v7; this bundle wants v2.7/v3. composer require will either fail or force an untenable downgrade. Don't try to solve it — vendor the generator code if you must.AppKernel, no bundles.php registration path, and no doctrine service container. A Symfony bundle cannot be "used" from a Laravel app without a bridge; treat the package as source material only.// @generated — do not edit) and a .gitattributes/lint rule, or you will lose hand edits silently.author vs posts). Verify every pair's inverse key names, especially self-referential relations (parent/children) which frequently come out wrong or missing.@Enums, JSON columns, and DB-level defaults are invisible to a metadata-driven generator. Same on the Laravel side with accessors, casts, and $appends — the generator sees columns/relations, not computed attributes.decimal → DS.attr('number') is a lossy float conversion; money/quantity columns are better as string in Ember. Decide this explicitly in your mapping table.type, id, constructor, and Ember-reserved model names will break the generated files. Add a denylist and a fail-loud check rather than silently emitting broken JS.doctrine:mapping:info (Symfony) or php artisan model:show Foo (Laravel) confirms which fields and relations are actually mapped. If a field is missing from the generated model, it's almost always absent from the mapping, not a generator bug.composer.json. Spend half a day writing a 150–250 line artisan command modeled on its output format; you'll get Laravel-native schema introspection, PHP 8+/Laravel 11 support, tests, and no dead dependency.How can I help you explore Laravel packages today?