ibrows/association-resolver-bundle
A Symfony bundle that resolves entity associations from identifiers or request data, letting you map incoming values to related Doctrine entities through configurable resolvers. Simplifies form binding, imports, and API payload handling with less boilerplate.
The bundle's premise is simple: instead of wiring Doctrine associations and hand-written repository lookups every time you need a related object, you tag a property or method with an annotation and let a resolver service fetch the association for you.
Minimal setup:
composer require ibrows/association-resolver-bundlenew Ibrows\AssociationResolverBundle\IbrowsAssociationResolverBundle() in app/AppKernel.php (Symfony ≤4) or config/bundles.php (Symfony 5+).doctrine/annotations present and the bundle's annotation directory autoloaded; check Resources/config/ for the service definitions and whether the resolver is public or private.Annotation/ (the annotation class and its options) and the resolver service class (typically Resolver/ or Service/). These two files tell you the entire contract — there is very little else in the bundle.Because the package has zero stars and zero dependents, budget an hour for source reading before you commit to it. Treat the annotation class as the authoritative documentation.
Annotation-driven resolution on entities. The natural pattern is to declare the association next to the property it belongs to, so the relationship is discoverable in the entity rather than scattered across services. Keep annotations on entities that are read-mostly; for write-heavy flows you will want explicit repository methods instead.
Inject the resolver, don't call it statically. Register the resolver as a normal service dependency in your controller or a dedicated factory. If the bundle's service is private in your Symfony version, alias it in services.yaml under a public id you control — future bundle upgrades won't silently break your injection.
Wrap resolution in a small application service. Rather than letting controllers depend on the bundle directly, put a thin AssociationFacade in your own code that calls the resolver and applies your caching, permission checks, and fallback logic. This gives you a one-file escape hatch if the bundle is abandoned — you swap the facade's internals and nothing else changes.
Batch before you loop. If you plan to resolve associations for a collection of entities, check whether the resolver supports a batch or collection call. If it does not, resolve eagerly before rendering a list rather than inside a Twig loop, and memoize results in a request-scoped array keyed by entity id.
Compose with Doctrine, don't replace it. Use the bundle for cross-cutting or non-mapped relations (e.g. links to entities in a separate bounded context or a legacy table). Keep true foreign-key relations as ordinary Doctrine associations — the ORM's identity map and lazy loading are far better tested.
Twig convenience. If you render associations frequently, add a small Twig extension in your app that proxies to your facade. Do not expose the resolver directly to templates; you lose the ability to cache or guard access.
composer.json and read the annotation class before relying on any option — undocumented behavior is the norm here.doctrine/annotations is installed and that entity annotation autoloading is configured; otherwise annotations silently resolve to nothing and you get null associations rather than an error.WHERE id IN (...) repository method.dump() the resolved object inside the facade, not inside a template. If resolution returns null unexpectedly, first verify the annotation is actually being read — a missing use statement for the annotation class is the most common cause.Resources/config/. If one exists, implement it for your own association types rather than forking the bundle. If not, decorate the resolver service in services.yaml — decoration is the safest way to add caching or logging without touching vendor code.How can I help you explore Laravel packages today?