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

Relation Laravel Package

amethyst/relation

Amethyst Relation is a Laravel package that extends Eloquent relationships with a cleaner API for defining, querying, and managing model relations. It simplifies complex relationship logic and supports common relation patterns out of the box.

View on GitHub
Deep Wiki
Context7

Getting Started

The amethyst/relation package is a small component of the Amethyst PHP framework family. It models relations — named associations (typically between modules or domain objects) — so that a container or module can declare "I depend on / relate to X" and have that relationship resolved consistently at boot or runtime. With zero stars and no dependents, treat the repository source as the canonical documentation.

Minimal steps:

  1. Install alongside the framework pieces it expects:

    composer require amethyst/relation
    

    Verify the require block in composer.json — this package is designed to sit next to amethyst/module (and usually amethyst/core / amethyst/kernel). Installing it standalone will give you the relation primitives but nothing to attach them to.

  2. Read these files first, in this order:

    • src/Relation.php (or RelationInterface.php) — the contract.
    • Any trait/abstract class the package exposes for consumers (e.g. a HasRelations-style trait).
    • tests/ — this is where the real usage examples live for a package this size. The test fixtures show the intended call sequence far better than the README.
  3. First use case: attach a relation to a module and read it back.

    $module->addRelation('cache', $cacheRelation);
    $module->getRelation('cache');
    

    The exact method names depend on the version — confirm against the trait/interface you found in step 2 before wiring it into application code.

  4. Only after the in-memory round-trip works should you hook it into the kernel's module-registration/boot path. That's where ordering and resolution semantics matter.

Implementation Patterns

Declarative relations on modules. The most common day-to-day pattern is to give each module a small set of named relations that describe what it needs from the rest of the system. Keep the relation name stable (it becomes a de-facto public key) and push the concrete object behind it:

final class BillingModule extends Module
{
    public function relations(): array
    {
        return [
            'gateway' => fn () => $this->container->get(PaymentGateway::class),
        ];
    }
}

Lazy closures (or whatever deferred-value mechanism the package version supports) avoid the classic boot-order deadlock where module A needs module B's services during construction.

Kernel-mediated resolution. In a multi-module app, do not have modules reach into each other directly. Register relations on the kernel/container and resolve by name at the point of use. This keeps the dependency graph inspectable and gives you one place to debug "who asked for what."

Relation as an extension point. If the package defines a RelationInterface, implement it for anything that is more than a plain service lookup — e.g. a relation that returns a collection, a lazily-constructed repository, or a proxy that defers a remote call. This is the cleanest way to add behavior without forking the package.

Testing pattern. Because relations are just named lookups, unit tests should assert on the relation map itself rather than on resolved objects:

$this->assertArrayHasKey('gateway', $module->relations());

Then have a separate integration test that boots two or three modules together and asserts the resolved graph. Keep the two layers distinct — the in-memory tests are fast and catch typos; the boot tests catch ordering bugs.

Integration tip: wrap relation access behind a single application-level service (e.g. Relations::get('gateway')) rather than scattering $module->getRelation(...) calls. When the package inevitably changes its API, you rewrite one method.

Gotchas and Tips

  • Documentation is effectively absent. Zero stars, zero dependents, no ecosystem. Before committing to it, read src/ end-to-end (it's likely under a few hundred lines) and pin the version in composer.json with an exact constraint. Do not use ^ on a package with no release discipline.

  • Version/API drift. Amethyst packages went through interface reshuffles. Method names like addRelation vs setRelation, and whether relations are callable, object, or string-keys, can differ between tags. Check the tag you install, not master.

  • Circular relations. Nothing in a lightweight relation container stops A→B→A. If relations are resolved eagerly at boot, you get infinite recursion or a half-initialized object. Prefer lazy resolution and add a boot-time cycle check in your own code if the package doesn't ship one.

  • Naming collisions. Relation names are global-ish within a module. Namespace them (billing.gateway) if you have more than a handful of modules, otherwise two modules will silently overwrite each other's slot.

  • Silent nulls. Most small lookup implementations return null for a missing relation rather than throwing. That turns a typo into a runtime Call to a member function on null three layers away. Wrap getRelation in your own accessor that throws a descriptive exception on miss.

  • Debugging. Dump the full relation map early (var_dump($module->relations())) at boot in dev. This immediately reveals ordering issues and duplicate keys. Add it to a debug command rather than leaving it in the boot path.

  • Extension points are your safety valve. If you need behavior the package doesn't offer (typed relations, validation, deferred resolution), implement RelationInterface or decorate the container rather than editing vendor code — there's no upstream activity to rely on for fixes.

  • Have an exit plan. Given the maintenance risk, isolate the package behind a thin internal interface (RelationRegistry) with one implementation backed by amethyst/relation. If you later replace it with a plain Symfony service locator or a PSR-11 container lookup, only that one class changes.

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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle