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

Association Resolver Bundle Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

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:

  1. composer require ibrows/association-resolver-bundle
  2. Register the bundle — new Ibrows\AssociationResolverBundle\IbrowsAssociationResolverBundle() in app/AppKernel.php (Symfony ≤4) or config/bundles.php (Symfony 5+).
  3. Confirm the annotation namespace is registered. Older Symfony projects need 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.
  4. Look first at 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.
  5. First use case: annotate a property on an entity with the association annotation pointing at a target entity, inject the resolver into a controller, and call the resolve method for that entity. Verify by dumping the returned object — this is the fastest way to learn what the annotation options actually do, because the README is thin.

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.

Implementation Patterns

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.

Gotchas and Tips

  • Maintenance risk is the headline issue. Zero stars, zero dependents, and a single-purpose scope mean you are effectively the maintainer. Pin the exact version in composer.json and read the annotation class before relying on any option — undocumented behavior is the norm here.
  • Annotation reader compatibility. The bundle predates PHP 8 attributes. On Symfony 6+ / PHP 8, ensure 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.
  • Null vs. exception. Test what the resolver returns when no association is found — some implementations throw, some return null. Normalize this in your facade so callers have one contract.
  • Circular resolution. If entity A's annotation resolves to B and B's resolves back to A, you can loop. Guard with a depth counter or a "currently resolving" set in your facade.
  • N+1 queries. The resolver almost certainly issues one query per call. Profile with the Symfony profiler on any list page before shipping; if the query count explodes, fall back to a hand-written WHERE id IN (...) repository method.
  • Debugging. 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.
  • Extension points. Check for a tagged-service or interface-based resolver chain in 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.
  • Migration prep. Assume you may need to replace this. Keep the facade interface narrow and Doctrine-free so that a future swap to explicit repository methods or a custom attribute is a mechanical change.
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.
mydnic/volet-feature-board-filament-plugin
wmde/email-address
refinery29/test-util
dees040/laravel-api-responses
teamzac/geocoder
ideatica/config-writer
keaton-php/pipe-dream
jacksonwebservices/laravel-user-suite
maksimru/conditional-laravel-debugbar
gismatul/nova-support-chat
gismatul/laravel-support-chat
networkrailbusinesssystems/oracle-api
alphabalex/messaging-made-easy
rawphp/warp
shootkiran/merobug
narakode/fineauth
numencode/wn-syncops-plugin
ibnnajjaar/mib-global-pay
refinery29/php-cs-fixer-config
parsnick/steak