schenke-io / laravel-relation-manager
Allow to plan, document and test model relations in Laravel
Installs: 457
Dependents: 1
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 2
pkg:composer/schenke-io/laravel-relation-manager
Requires
- php: ^8.2
- archtechx/enums: ^1.1
- illuminate/contracts: ^10.0|^11.0|^12.0
- nette/php-generator: ^4.1.6
- spatie/laravel-data: ^3.12|^4.13
- spatie/laravel-package-tools: ^1.0
Requires (Dev)
- larastan/larastan: ^2.0|^3.0
- laravel/pint: ^1.21
- mockery/mockery: ^1.4.4
- nunomaduro/collision: ^8.5
- orchestra/testbench: ^9.5|^10.0
- pestphp/pest: ^3.7
- schenke-io/packaging-tools: ^v0.0
- spatie/laravel-ray: ^1.26
- dev-main
- v1.5.6
- v1.5.5
- v1.5.4
- v1.5.3
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.1
- v1.3.1
- v1.3.0
- v1.2.0
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.2
- v1.0.1
- v1.0.0
- v0.7.2
- v0.7.1
- v0.7.0
- v0.6.0
- v0.5.10
- v0.5.9
- v0.5.8
- v0.5.7
- v0.5.6
- v0.5.5
- v0.5.4
- v0.5.3
- v0.5.2
- v0.5.1
- v0.5.0
- v0.4.1
- v0.4.0
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- v0.0.3
- v0.0.1
- dev-dependabot/github_actions/actions/checkout-6
- dev-dependabot/github_actions/stefanzweifel/git-auto-commit-action-7
- dev-dependabot/github_actions/dependabot/fetch-metadata-2.3.0
This package is auto-updated.
Last update: 2026-01-15 13:35:51 UTC
README
Laravel Relation Manager
Developing complex Laravel applications with many models can be difficult. Laravel Relation Manager helps by bringing all your model relationships together. It creates tests to make sure they work and documents them for easy reference. This saves you time, improves code quality, and keeps your project organized.
- Laravel Relation Manager
- Examples and Guides
Installation
You can install the package via composer:
composer require schenke-io/laravel-relation-manager
After installation, you can start by scanning your models and generating the initial .relationships.json file:
php artisan relation:extract
Workflow
Laravel Relation Manager helps you maintain consistency in your Eloquent relationships through a simple three-step process:
- Extract:
php artisan relation:extract- Scans your models and saves the relationship state to.relationships.json. - Verify:
php artisan relation:verify- Ensures your code implementation matches the defined relationship state. - Draw:
php artisan relation:draw [filename]- Generates visualization (diagrams and tables) of your model relationships.
The Draw Command
The relation:draw command generates a comprehensive Markdown file (default: RELATIONS.md) that includes:
- Model relations table: Listing direct and indirect relations for each model.
- Table relations diagram: A visual representation of your database schema.
- Database overview: Expected tables and their foreign key columns.
- Relationship details: A complete list of all defined relationships.
You can optionally provide a filename to override the default path.
Understanding the Diagram
In the Mermaid diagram, arrows represent relationships between tables.
- Colors:
- Green (
#2ecc71): Standard Eloquent relations (One-to-One, One-to-Many). - Blue (
#3498db): Polymorphic relations. - Orange (
#e67e22): Many-to-Many relations.
- Green (
- Line Styles:
==>: Standard direct relations.-->: Polymorphic relations.<==>: Many-to-Many relations.
FAQ: Why is there an arrow from tags to regions?
This occurs when a model (like Tag) has a relationship method pointing to another model (like Region). Even if the database foreign key is on a pivot table or the other model, the diagram reflects the intent of the relationship method defined in the model.
Suggestion: If you want to exclude certain methods from the diagram, use the #[Relation(EloquentRelation::noRelation)] attribute.
Configuration
The .relationships.json file contains a config section to customize the behavior:
markdown_path: Path where the relations documentation will be generated (default:RELATIONS.md).model_path: Directory where your Eloquent models are located (default:app/Models).use_mermaid: Boolean to toggle between Mermaid (default) and Graphviz diagram generation.
Examples and Guides
This guide provides practical examples of how to use the Laravel Relation Manager with its new features.
1. Automatic Discovery
The easiest way to get started is by letting the package discover your relations automatically. Ensure your model methods have proper return type hints.
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class User extends Model { public function posts(): HasMany { return $this->hasMany(Post::class); } }
When you run php artisan relation:extract, this relation will be automatically detected and saved to .relationships.json.
2. Declarative Relations via Attributes
Sometimes you might want to provide additional metadata to your relationships or explicitly mark methods to be ignored.
On the Method Level
use SchenkeIo\LaravelRelationManager\Attributes\Relation; use SchenkeIo\LaravelRelationManager\Enums\EloquentRelation as RelationEnum; class User extends Model { #[Relation(RelationEnum::hasMany, Post::class)] public function posts() { return $this->hasMany(Post::class); } }
Automatic Reverse Relations
You can tell the scanner to automatically inject the inverse relation into the related model:
#[Relation(RelationEnum::hasMany, Comment::class, addReverse: true)] public function comments() { return $this->hasMany(Comment::class); }
Suppressing Relationships
If you have a method that should not be treated as a relationship, you can explicitly mark it with noRelation:
use SchenkeIo\LaravelRelationManager\Attributes\Relation; use SchenkeIo\LaravelRelationManager\Enums\EloquentRelation as RelationEnum; class User extends Model { #[Relation(RelationEnum::noRelation)] public function internalMethod() { // this will be ignored by the scanner } }
3. Testing Your Relations
Using PHPUnit
Add the RelationTestTrait trait to your test class:
use SchenkeIo\LaravelRelationManager\Phpunit\RelationTestTrait; class ModelRelationTest extends TestCase { use RelationTestTrait; public function test_user_has_many_posts() { $this->assertModelHasMany(User::class, Post::class); } }
Using Pest
If you are using Pest, you can use the fluent expectations:
it('has the correct relations', function () { expect(User::class)->toHasMany(Post::class); expect(Post::class)->toBelongsTo(User::class); });
4. Visualizing Relations
Generate a diagram or a Markdown table of your relations:
php artisan relation:draw
By default, this command uses the data from .relationships.json. It supports:
- Mermaid.js: Default tool for embedding diagrams in Markdown (GitHub/GitLab compatible).
- Graphviz: An alternative that generates a PNG file (requires
dotto be installed). This is automatically used ifuse_mermaidis set tofalsein the configuration.
Mermaid Diagram Example
flowchart LR
User ==> Post
Post ==> Comment
linkStyle 0 stroke:#2ecc71,stroke-width:3px
linkStyle 1 stroke:#2ecc71,stroke-width:3px
Loading
Relationship Table Example
| Model | Method(): Relation | Related Model | Reverse Relation |
|---|---|---|---|
| User | posts(): hasMany | Post | Post::author |
profile(): hasOne | Profile | Profile::user |
Here an example of a generated markdown file.
Testing Relationships
The package provides built-in tools to verify that your model implementation matches your .relationships.json file. This ensures that your documentation, diagrams, and actual code are always in sync.
Strict vs. Loose Mode
- Loose Mode (Default): Validates that every relationship defined in your
.relationships.jsonfile exists in your code. It ignores extra relationships in your code that are not defined in the JSON. - Strict Mode: In addition to Loose Mode checks, it also fails if it finds relationships in your models that are not defined in your
.relationships.jsonfile. This is recommended for maintaining a complete and accurate documentation of your data model.
PHPUnit Integration
To use with PHPUnit, create a test class that extends AbstractRelationTest.
<?php namespace Tests\Feature; use SchenkeIo\LaravelRelationManager\Phpunit\AbstractRelationTest; class RelationshipTest extends AbstractRelationTest { /** * Optional: Path to your relationships file. * Defaults to the one found by PathResolver (.relationships.json). */ protected ?string $relationshipJsonPath = null; /** * Optional: Directory containing your models. * Defaults to the one defined in .relationships.json config * or 'app/Models'. */ protected ?string $modelDirectory = null; /** * Set to true for Strict Mode. */ protected bool $strict = true; }
The base class provides the following tests:
test_laravel_environment: Ensures the test runs within a Laravel environment.test_relationship_json_exists_and_is_valid: Verifies that the JSON file is present and correctly formatted.test_models_match_json_state: Compares the model implementation against the JSON definition.
Pest PHP Integration
For Pest, you can use the RelationTestBridge to quickly register all necessary tests in a single call.
<?php use SchenkeIo\LaravelRelationManager\Pest\RelationTestBridge; RelationTestBridge::all( relationshipJsonPath: null, // optional, defaults to PathResolver modelDirectory: null, // optional, defaults to config or 'app/Models' strict: true // recommended, defaults to false );
This will automatically register three tests in your Pest file:
test('laravel environment', ...)test('relationship json exists and is valid', ...)test('models match json state', ...)
README generated at 2026-01-15 13:09:50 using packaging-tools
