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 Join With Laravel Package

msafadi/laravel-eloquent-join-with

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation: Run composer require msafadi/laravel-eloquent-join-with and publish the config if needed (php artisan vendor:publish --provider="Safadi\EloquentJoinWith\EloquentJoinWithServiceProvider").
  2. Apply Trait: Add use Safadi\EloquentJoinWith\Database\Concerns\JoinWith; to your Eloquent model (e.g., User.php).
  3. First Use Case:
    // Replace eager loading with a single join query
    $users = User::joinWith('posts')->get();
    
    • Assumes posts() is a HasOne or BelongsTo relationship.

Where to Look First

  • Package Docs: GitHub README for usage examples.
  • Model Relationships: Verify relationships are defined as HasOne/BelongsTo (e.g., public function posts() { return $this->hasOne(Post::class); }).
  • Query Builder: Check joinWith() method in the trait for available options (e.g., select(), where()).

Implementation Patterns

Core Workflows

  1. Basic Joins:

    // Replace `with('posts')->find(1)` with:
    User::joinWith('posts')->find(1);
    
    • Performance Gain: Single query vs. N+1 eager loading.
  2. Conditional Joins:

    User::joinWith('posts')->whereHas('posts', function($q) {
        $q->where('published', true);
    })->get();
    
    • Use whereHas to filter joined tables.
  3. Selective Columns:

    User::joinWith(['posts' => function($query) {
        $query->select('id', 'title');
    }])->get();
    
    • Optimize joined table columns.
  4. Nested Joins:

    User::joinWith(['posts' => function($query) {
        $query->joinWith('comments');
    }])->get();
    
    • Supports nested joinWith for deeper relationships.
  5. Integration with Existing Code:

    • Replace with() calls in repositories/services:
      // Before:
      $user = User::with('posts')->find($id);
      
      // After:
      $user = User::joinWith('posts')->find($id);
      

Advanced Patterns

  • Dynamic Joins:

    $relations = request()->input('relations', []);
    User::joinWith($relations)->get();
    
    • Useful for API endpoints with dynamic fields.
  • Hybrid Queries:

    User::select('users.*')
        ->joinWith('posts')
        ->where('users.active', true)
        ->get();
    
    • Combine joinWith with custom select() clauses.
  • Pagination:

    User::joinWith('posts')->paginate(10);
    
    • Works seamlessly with Laravel’s pagination.
  • API Resources:

    // UserResource.php
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'posts' => $this->whenLoaded('posts', fn() => $this->posts),
        ];
    }
    
    • Ensure joined data is accessible via relationships.

Gotchas and Tips

Pitfalls

  1. Unsupported Relationships:

    • Error: joinWith only works with HasOne/BelongsTo. Using HasMany/BelongsToMany will fail silently or throw errors.
    • Fix: Stick to supported relationships or use with() for others.
  2. Missing Foreign Keys:

    • Error: If the foreign key doesn’t match the relationship definition, joins may fail or return incorrect data.
    • Fix: Explicitly define keys in relationships:
      public function posts() {
          return $this->hasOne(Post::class, 'user_id', 'id');
      }
      
  3. Over-Eager Joins:

    • Performance Issue: Joining too many tables can bloat queries. Monitor query logs (DB::enableQueryLog()).
    • Fix: Limit joins to essential relationships.
  4. Caching Quirks:

    • Issue: Joined data may not play nicely with Laravel’s model caching (e.g., remember()).
    • Fix: Disable caching for joined models or use fresh():
      $user = User::joinWith('posts')->find($id)->fresh();
      
  5. Soft Deletes:

    • Behavior: Joined models with soft deletes may include deleted records unless filtered.
    • Fix: Add whereNull('posts.deleted_at') to the join query.

Debugging Tips

  • Query Logging:

    DB::enableQueryLog();
    User::joinWith('posts')->get();
    dd(DB::getQueryLog());
    
    • Verify the generated SQL matches expectations.
  • Relationship Debugging:

    // Check if a relationship is recognized
    dd(app(User::class)->getRelationships());
    
  • Common Errors:

    • "Call to undefined method": Ensure the trait is properly namespaced (use Safadi\EloquentJoinWith\Database\Concerns\JoinWith;).
    • SQL Syntax Errors: Use ->toSql() to inspect the query:
      $query = User::joinWith('posts')->toSql();
      

Extension Points

  1. Custom Join Logic:

    • Override the joinWith method in your model:
      public function scopeCustomJoinWith($query, $relations) {
          return $query->joinWith($relations)->select('users.*');
      }
      
    • Usage: User::customJoinWith(['posts'])->get();
  2. Global Configuration:

    • Publish the config (php artisan vendor:publish) to customize:
      • Default join behavior.
      • Global select clauses.
      • Excluded relationships.
  3. Testing:

    • Mock the trait for unit tests:
      $user = new User();
      $user->setJoinWithMock(true); // Hypothetical; check package docs for actual method.
      
  4. Performance Tuning:

    • Indexing: Ensure foreign keys are indexed in the database.
    • Query Scoping: Use joinWith in scopes:
      public function scopeWithPosts($query) {
          return $query->joinWith('posts');
      }
      
      Usage: User::withPosts()->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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor