Load() and with() functions act inconsistent when using relationships inside relationships #33503
-
        
 Description:Laravel allows using relational values inside other relations. This can be useful when applying additional  Using the framework provided  When  Steps To Reproduce:Schema:
 
 
 
 
 
 Models:class Task extends Model
{
    public function group()
    {
        dump($this->team);
        return $this->hasOne(Group::class, 'id', 'group_id');
    }
    public function team()
    {
        return $this->hasOne(Team::class, 'id', 'team_id');
    }
}
class Group extends Model
{
}
class Team extends Model
{
}ExamplesWorking Example $task = \App\Task::query()->first();
dump($task->group);
// Result dumps `$task->team` from inside `team()`
// then `$task->group`Not Working Examples $task = \App\Task::query()->with('group')->first();
dump($task->group);
// Result dumps null from inside `team()`
// then `$task->group`$task = \App\Task::query()->first();
$task->load('group');
dump($task->group);
// Result dumps null from inside `team()`
// then `$task->group` | 
  
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
        
 What constraint would you add in this example? Eager loading fetches the groups of multiple tasks with a single query and doesn't allow you to have individual constraints per task.  | 
  
Beta Was this translation helpful? Give feedback.
-
| 
         @staudenmeir The long answer to my exact use case is as follows: Code Snippetsclass User extends Authenticatable
{
    protected $connection = 'default';
    public function externalGroup()
    {
        return $this->belongsTo(ExternalGroup::class, 'group_id', 'group_id');
    }
}
class ExternalGroup extends Model
{
    protected $connection = 'non_default';
}
class Thing extends Model
{
    protected $connection = 'non_default';
    public function task()
    {
        return $this->hasOne(Task::class, 'id', 'task_id');
    }
    public function primaryTask()
    {
        return $this->hasOneThrough(
            Task::class,
            GroupTask::class,
            'task_id',
            'id',
            'task_id',
            'primary_task_id'
        // auth()->user()->externalGroup does not work as intended
        )->where('group_tasks.group_id', auth()->user()->externalGroup->id);
    }
}
class Task extends Model
{
    protected $connection = 'non_default';
    public function scopePrimaryTasksByThing()
    {
        $taskIds = app(Thing::class)
            ->query()
            // Eager loading here causes the problem
            ->with('primaryTask')
            ->get()
            ->pluck('primaryTask.id');
        $query->whereIn('tasks.id', $taskIds->toArray());
    }
}
class TaskController extends Controller
{
    public function index()
    {
        return app(Task::class)->query()->primaryTasksByThing()->get();
    }
}Schema:
 Overview:
 Problem:
 Work Around:
 Example: public function scopePrimaryTasksByThing()
{
    // This line was added
    auth()->user()->load('externalGroup');
    $taskIds = app(Thing::class)
        ->query()
        // Eager loading here causes the problem
        ->with('primaryTask')
        ->get()
        ->pluck('primaryTask.id');
    $query->whereIn('tasks.id', $taskIds->toArray());
} | 
  
Beta Was this translation helpful? Give feedback.
-
| 
         We had a discussion about this behavior recently: #33266 
 The underlying cause is actually different. 
 What do you mean by "normal models"?  | 
  
Beta Was this translation helpful? Give feedback.
-
| 
         I'm not sure I would categorize this as a "bug" at this point. It seems to be something we just didn't anticipate or plan to support.  | 
  
Beta Was this translation helpful? Give feedback.
We had a discussion about this behavior recently: #33266
The underlying cause is actually different.
What do you mean by "normal models"?