PHPackages                             schenke-io/laravel-relation-manager - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. schenke-io/laravel-relation-manager

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

schenke-io/laravel-relation-manager
===================================

Allow to plan, document and test model relations in Laravel

v2.0.4(3mo ago)0527↓50%[2 PRs](https://github.com/schenke-io/laravel-relation-manager/pulls)1MITPHPPHP ^8.3CI passing

Since Aug 26Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/schenke-io/laravel-relation-manager)[ Packagist](https://packagist.org/packages/schenke-io/laravel-relation-manager)[ Docs](https://github.com/schenke-io/laravel-relationship-manager)[ RSS](/packages/schenke-io-laravel-relation-manager/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (11)Versions (56)Used By (1)

[![Coverage](workbench/resources/md/svg/coverage.svg)](workbench/resources/md/svg/coverage.svg)[![PHPStan](workbench/resources/md/svg/phpstan.svg)](workbench/resources/md/svg/phpstan.svg)[![Version](https://camo.githubusercontent.com/5bc3243e2c48e1c2397626485c12a7001c8771e0129cabc4a276b7e6f833daae/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736368656e6b652d696f2f6c61726176656c2d72656c6174696f6e2d6d616e616765723f7374796c653d666c6174)](https://packagist.org/packages/schenke-io/laravel-relation-manager)[![Downloads](https://camo.githubusercontent.com/ac586c44a29270031c5278ec95872fb0fcfc8f3d058753056ecfe18112c9b664/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736368656e6b652d696f2f6c61726176656c2d72656c6174696f6e2d6d616e616765723f7374796c653d666c6174)](https://packagist.org/packages/schenke-io/laravel-relation-manager)[![Tests](https://github.com/schenke-io/laravel-relation-manager/actions/workflows/run-tests.yml/badge.svg)](https://github.com/schenke-io/laravel-relation-manager/actions/workflows/run-tests.yml)[![License](https://camo.githubusercontent.com/c7ab10fef244ca738df315d6d96cf0cd70459d0e553f07a631c1d3d439629819/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f736368656e6b652d696f2f6c61726176656c2d72656c6174696f6e2d6d616e616765723f7374796c653d666c6174)](https://github.com/schenke-io/laravel-relation-manager/blob/main/LICENSE.md)[![PHP](https://camo.githubusercontent.com/032cd281bee92e40858b517a768fb390023acebf440296df48fe4249a84b0492/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f736368656e6b652d696f2f6c61726176656c2d72656c6174696f6e2d6d616e616765723f7374796c653d666c6174)](https://packagist.org/packages/schenke-io/laravel-relation-manager)

Schenke Io Laravel Relation Manager
===================================

[](#schenke-io-laravel-relation-manager)

> Allow to plan, document and test model relations in Laravel

[![cover](workbench/resources/md/cover.png)](workbench/resources/md/cover.png)

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.

- [Schenke Io Laravel Relation Manager](#schenke-io-laravel-relation-manager)
    - [Installation](#installation)
    - [Workflow](#workflow)
        - [The Draw Command](#the-draw-command)
            - [Understanding the Diagram](#understanding-the-diagram)
        - [Configuration](#configuration)
- [Examples and Guides](#examples-and-guides)
    - [1. Automatic Discovery](#1-automatic-discovery)
    - [2. Declarative Relations via Attributes](#2-declarative-relations-via-attributes)
        - [On the Method Level](#on-the-method-level)
        - [Automatic Reverse Relations](#automatic-reverse-relations)
        - [Suppressing Relationships](#suppressing-relationships)
    - [3. Testing Your Relations](#3-testing-your-relations)
        - [Using PHPUnit](#using-phpunit)
        - [Using Pest](#using-pest)
    - [4. Visualizing Relations](#4-visualizing-relations)
        - [Mermaid Diagram Example](#mermaid-diagram-example)
        - [Relationship Table Example](#relationship-table-example)
    - [Testing Relationships](#testing-relationships)
        - [Strict vs. Loose Mode](#strict-vs-loose-mode)
        - [PHPUnit Integration](#phpunit-integration)
        - [Pest PHP Integration](#pest-php-integration)

Installation
------------

[](#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
--------

[](#workflow)

Laravel Relation Manager helps you maintain consistency in your Eloquent relationships through a simple three-step process:

1. **Extract**: `php artisan relation:extract` - Scans your models and saves the relationship state to `.relationships.json`.
2. **Verify**: `php artisan relation:verify` - Ensures your code implementation matches the defined relationship state.
3. **Draw**: `php artisan relation:draw [filename]` - Generates visualization (diagrams and tables) of your model relationships.

### The Draw Command

[](#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

[](#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.
- **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

[](#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
===================

[](#examples-and-guides)

This guide provides practical examples of how to use the Laravel Relation Manager with its new features.

1. Automatic Discovery
----------------------

[](#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
---------------------------------------

[](#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

[](#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

[](#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

[](#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
-------------------------

[](#3-testing-your-relations)

### Using PHPUnit

[](#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

[](#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
------------------------

[](#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 `dot` to be installed). This is automatically used if `use_mermaid` is set to `false` in the configuration.

### Mermaid Diagram Example

[](#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

[](#relationship-table-example)

ModelMethod(): RelationRelated ModelReverse RelationUser`posts(): hasMany`PostPost::author`profile(): hasOne`ProfileProfile::userHere an example of a [generated markdown](workbench/resources/md/relations.md) file.

Testing Relationships
---------------------

[](#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

[](#strict-vs-loose-mode)

- **Loose Mode (Default)**: Validates that every relationship defined in your `.relationships.json` file 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.json` file. This is recommended for maintaining a complete and accurate documentation of your data model.

---

### PHPUnit Integration

[](#phpunit-integration)

To use with PHPUnit, create a test class that extends `AbstractRelationTest`.

```
