Link Definitions
Fluent API for defining cross-module relationships
Creating a Link Definition
Option 1: Fluent API
use Esegments\ModularArchitecture\Facades\Links;
Links::define('TaxProductLink')
->requires('Tax', 'Products')
->belongsTo(Product::class, 'taxClass', TaxClass::class, 'tax_class_id')
->hasMany(TaxClass::class, 'products', Product::class, 'tax_class_id');
Option 2: Link Definition Class
Create in app/Links/ directory:
namespace Modules\TaxProductLink\Links;
use Esegments\ModularArchitecture\Links\LinkDefinition;
use Modules\Products\Models\Product;
use Modules\Tax\Models\TaxClass;
class TaxProductLink extends LinkDefinition
{
protected string $name = 'TaxProductLink';
protected array $requires = ['Tax', 'Products'];
public function define(): void
{
// Relationships
$this->belongsTo(Product::class, 'taxClass', TaxClass::class, 'tax_class_id');
$this->hasMany(TaxClass::class, 'products', Product::class, 'tax_class_id');
// Macros
$this->macro(Product::class, 'taxClassName', fn () => $this->taxClass?->name);
}
}
Relationship Methods
belongsTo
$link->belongsTo(
Product::class, // Model to add relationship to
'taxClass', // Relationship method name
TaxClass::class, // Related model
'tax_class_id' // Foreign key on Product
);
Usage:
$product->taxClass; // Returns TaxClass|null
hasMany
$link->hasMany(
TaxClass::class, // Model to add relationship to
'products', // Relationship method name
Product::class, // Related model
'tax_class_id' // Foreign key on Product
);
Usage:
$taxClass->products; // Returns Collection<Product>
hasOne
$link->hasOne(
User::class, // Model to add relationship to
'profile', // Relationship method name
Profile::class, // Related model
'user_id' // Foreign key on Profile
);
belongsToMany
$link->belongsToMany(
Product::class, // Model to add relationship to
'categories', // Relationship method name
Category::class, // Related model
'category_product', // Pivot table name
'product_id', // Foreign pivot key
'category_id' // Related pivot key
);
morphTo / morphMany / morphToMany
// Polymorphic relationships
$link->morphTo(Comment::class, 'commentable');
$link->morphMany(Post::class, 'comments', Comment::class, 'commentable');
Adding Macros
Macros add methods to models:
Accessor Macro
$link->macro(Product::class, 'taxClassName', function () {
return $this->taxClass?->name;
});
Usage:
$product->taxClassName; // Returns string|null
Scope Macro
$link->macro(Product::class, 'scopeWithTax', function ($query) {
return $query->whereNotNull('tax_class_id');
});
$link->macro(Product::class, 'scopeTaxable', function ($query) {
return $query->whereHas('taxClass');
});
Usage:
Product::withTax()->get();
Product::taxable()->get();
Query Macro
$link->macro(Product::class, 'forTaxClass', function (int $taxClassId) {
return static::where('tax_class_id', $taxClassId)->get();
});
Usage:
$products = Product::forTaxClass(1);
Eager Loading
Configure default eager loads:
$link->eagerLoad(ProductResource::class, 'table', ['taxClass']);
$link->eagerLoad(ProductResource::class, 'form', ['taxClass.rates']);
Filament Integration
Relation Manager
$link->relationManager(
ProductResource::class,
TaxClassRelationManager::class
);
Form Section
$link->formSection(
ProductResource::class,
'tax',
fn () => Section::make('Tax')->schema([
Select::make('tax_class_id')
->relationship('taxClass', 'name')
])
);
Table Column
$link->tableColumn(
ProductResource::class,
TextColumn::make('taxClass.name')->label('Tax Class')
);
Link Registration
Links are auto-discovered from app/Links/ directories. Or register manually:
// In a service provider
public function boot(): void
{
Links::define('MyLink')
->requires('ModuleA', 'ModuleB')
->belongsTo(...);
}
Link Lifecycle
- Discovery: LinkBridge scans
app/Links/directories - Registration: Link definitions are registered with LinkRegistry
- Activation Check: Required modules must be enabled
- Boot: Relationships and macros are applied
// Check if link is active
if (Links::isEnabled('TaxProductLink')) {
// Relationships are available
$product->taxClass;
}
Debugging Links
# List all links
php artisan modular:links
# Check link status
php artisan modular:links:status TaxProductLink
// Programmatic debugging
$status = Links::status();
$summary = Links::summary();