Weave Code
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

Laravel Eloquent Relationships Laravel Package

zing/laravel-eloquent-relationships

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require zing/laravel-eloquent-relationships
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="Zing\LaravelEloquentRelationships\ServiceProvider"
    
  2. First Use Case: Define a custom relationship in your Eloquent model:

    use Zing\LaravelEloquentRelationships\Relationships\HasManyThrough;
    
    class User extends Model
    {
        public function ordersThroughAdmin()
        {
            return $this->hasManyThrough(
                Order::class,
                Admin::class,
                'user_id', // Local key on User
                'admin_id', // Foreign key on Admin
                'id', // Local key on Admin
                'user_id' // Foreign key on Order
            );
        }
    }
    
  3. Key Files:

    • config/zing-eloquent-relationships.php (if published)
    • app/Models/ (for custom relationship definitions)
    • vendor/zing/laravel-eloquent-relationships/src/ (for advanced usage)

Implementation Patterns

Common Workflows

1. Multi-Level Relationships

Use HasManyThrough for nested relationships:

// User → Admin → Order
$user->ordersThroughAdmin()->get();

2. Polymorphic Relationships

Extend polymorphic behavior with custom logic:

use Zing\LaravelEloquentRelationships\Relationships\MorphToMany;

class Post extends Model
{
    public function tags()
    {
        return $this->morphToMany(
            Tag::class,
            'taggable',
            'post_tag',
            'tag_id',
            'taggable_id',
            'taggable_type'
        );
    }
}

3. Conditional Relationships

Dynamically toggle relationships based on logic:

public function activeOrders()
{
    return $this->hasMany(Order::class)
        ->when($this->isPremium(), function ($query) {
            return $query->where('status', 'active');
        });
}

4. Custom Query Scoping

Attach query constraints to relationships:

use Zing\LaravelEloquentRelationships\Traits\ScopesRelationships;

class User extends Model
{
    use ScopesRelationships;

    public function scopeActive($query)
    {
        return $query->where('active', true);
    }

    public function orders()
    {
        return $this->hasMany(Order::class)->active();
    }
}

5. Relationship Caching

Cache relationship results for performance:

public function orders()
{
    return $this->hasMany(Order::class)->remember();
}

Integration Tips

  1. Service Providers: Register custom relationship macros in AppServiceProvider:

    use Zing\LaravelEloquentRelationships\Facades\Relationship;
    
    public function boot()
    {
        Relationship::macro('customRelation', function () {
            return $this->hasMany(CustomModel::class);
        });
    }
    
  2. API Responses: Use relationships in API resources:

    public function toArray($request)
    {
        return [
            'orders' => $this->ordersThroughAdmin()->take(5)->get(),
        ];
    }
    
  3. Testing: Mock relationships in PHPUnit:

    $user = User::factory()->create();
    $user->shouldReceive('ordersThroughAdmin')
         ->once()
         ->andReturn(collect([Order::factory()->make()]));
    
  4. Database Observers: Trigger logic on relationship changes:

    Order::observe(OrderObserver::class);
    
    class OrderObserver
    {
        public function saved(Order $order)
        {
            $order->user->touch(); // Update user's last_order_at
        }
    }
    

Gotchas and Tips

Pitfalls

  1. N+1 Queries: Always eager-load relationships to avoid N+1 issues:

    $users = User::with('ordersThroughAdmin')->get();
    
  2. Circular References: Avoid infinite loops in serializable models:

    public function toArray()
    {
        return [
            'id' => $this->id,
            'orders' => $this->ordersThroughAdmin->pluck('id'), // Avoid loading full objects
        ];
    }
    
  3. Foreign Key Mismatches: Double-check foreign key names in HasManyThrough:

    // Wrong: Assumes default keys
    $this->hasManyThrough(Order::class, Admin::class);
    
    // Correct: Explicit keys
    $this->hasManyThrough(Order::class, Admin::class, 'user_id', 'admin_id', 'id', 'user_id');
    
  4. Polymorphic Ambiguity: Ensure taggable_type is consistent across models in MorphToMany.

  5. Cache Invalidation: Clear cached relationships after data changes:

    $user->ordersThroughAdmin()->fresh();
    

Debugging

  1. Query Logging: Enable Eloquent query logging:

    DB::enableQueryLog();
    $user->ordersThroughAdmin()->get();
    dd(DB::getQueryLog());
    
  2. Relationship Introspection: Debug relationship definitions:

    dd($user->ordersThroughAdmin->getQuery()->toSql());
    
  3. Macro Conflicts: Check for naming collisions in custom macros:

    Relationship::hasMacro('customRelation') // Verify before registering
    

Tips

  1. Performance Optimization: Use select() to limit loaded columns:

    $user->ordersThroughAdmin()->select('id', 'amount');
    
  2. Dynamic Relationships: Build relationships dynamically:

    public function getRelationValue($key)
    {
        if ($key === 'dynamicOrders') {
            return $this->hasMany(Order::class)->where('status', 'pending');
        }
        return parent::getRelationValue($key);
    }
    
  3. Configuration Overrides: Override default behavior in config/zing-eloquent-relationships.php:

    'default_relationships' => [
        'orders' => 'ordersThroughAdmin',
    ],
    
  4. Laravel Scout Integration: Index relationships for search:

    use Zing\LaravelEloquentRelationships\Scout\Searchable;
    
    class Order extends Model
    {
        use Searchable;
    
        public function searchableAttributes()
        {
            return ['user_id', 'admin_id'];
        }
    }
    
  5. API Rate Limiting: Limit relationship queries in API routes:

    Route::middleware(['throttle:60,1'])->group(function () {
        Route::get('/users/{user}/orders', [UserController::class, 'orders']);
    });
    
  6. Soft Deletes: Handle soft-deleted relationships:

    $user->ordersThroughAdmin()->withTrashed()->get();
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope