Eager loading not working
Closed this issue · 2 comments
This is a minimal example that illustrates the issue:
suppose you have a One To Many relationship between users
and posts
Migrations
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id')->unsigned();
$table->bigInteger('base_id')->unsigned();
$table->string('name');
$table->timestamps();
});
Schema::create('super_users', function (Blueprint $table) {
$table->bigIncrements('id')->unsigned();
$table->bigInteger('base_id')->unsigned();
$table->string('super_name');
$table->timestamps();
});
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id')->unsigned();
$table->text('title')->nullable();
$table->integer('user_id')->unsigned();
$table->timestamps();
});
Models
class User extends InheritableModel
{
use HasFactory;
public $table = "users";
protected $guard =[
'id'
];
public function posts()
{
return $this->hasMany(Post::class, 'user_id');
}
// factory method
}
class SuperUser extends User
{
use HasFactory;
public $table = "super_users";
protected $guard =[
'id'
];
// skipping factory method to save space
}
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
Create some SuperUsers and associated posts:
SuperUser::factory()->count(10)->create()->each(function ($user) {
$posts = Post::factory()->count(rand(1, 5))->make();
$user->posts()->saveMany($posts);
});
The issue is that because the child class 'SuperUser' was used to create the record, the following code won't load the post data, though, all the users are loaded correctly.
$res = User::with('posts')->get();
But in some situation in my code I need to retrieve all user independently with theirs associated posts
0 => array:6 [▼
"id" => 1
"base_id" => 21
"super_name" => "SuperUser"
"created_at" => null
"updated_at" => null
"name" => "set from super user"
]
To get the post loaded i'm obliged to load the data with the same class that is used in my factory.
$res = SuperUser::with('posts')->get(); // Notice the SuperUser instead of User
0 => array:7 [▼
"id" => 1
"base_id" => 21
"super_name" => "SuperUser"
"created_at" => null
"updated_at" => null
"name" => "set from super user"
"posts" => array:5 [▼
0 => array:5 [▶]
1 => array:5 [▶]
2 => array:5 [▶]
3 => array:5 [▶]
4 => array:5 [▶]
]
]
Question: How can I load all data with all the associated relations? I need to list them all users and super users
Thanks
Apologies for the slow reply. I've added some code recently to handle relations. I'll set up a test project with your specific requirement and double check it is working as expected but in theory this should work since version 1.0.15
.
@Oliamster I've recreated the scenario using the latest release 1.0.20
and the relations are loading fine with both:
$res = User::with('posts')->get();
$res = SuperUser::with('posts')->get();
Which should be the case since 1.0.15
. If you're debugging you'll find all the relations in the $relations
property of the top object (in this case SuperUser
), as opposed to $attributes
which are distributed up the hierarchy.
Let me know if there's any problems.