Laravel Eloquent hasMany关联预加载失效问题求助
Hey there, let's figure out why your eager loading isn't working and fix it up!
The main issue here is that you're missing the meta_value field in the select clause of your phones relationship on the Customer model. When Laravel does eager loading, it needs this field to match each Phone record back to its corresponding Customer. Without it, Laravel can't map the Phone data to the right Customer, so you end up with empty collections.
Also, there are a couple of small mistakes in your controller test code that we should clean up too.
Fix 1: Update the Customer Model's phones Relationship
Add meta_value to the selected fields so Laravel can handle the eager loading matching correctly:
/* Customer Model*/ namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Customer extends Model { use SoftDeletes; // Don't forget to use the trait if you're using soft deletes! /** * Get the Phone List. */ public function phones(){ return $this->hasMany('App\Phone','meta_value', 'id') ->select('id as phone_id','meta_value','contact_number as phone','contact_number','country_code','type','dial_code') ->where('meta_key','customer'); } }
Fix 2: Correct Your Controller Test Code
Let's fix the eager loading syntax for both single and multiple customers:
Single Customer
// Correct eager loading for a single customer $customer = Customer::with('phones')->find(448); print_r($customer); // Phones will be loaded properly now // Or if you want lazy load after fetching the model $customer = Customer::find(448); $customer->load('phones'); // This will work now too print_r($customer->phones);
Note: Customer::find('448')->with('phones')->get() was incorrect because find() already returns a single model, then get() wraps it in a collection — that's not what you intended.
Multiple Customers
$customers = Customer::where('id', '>', '447')->with('phones')->get(); print_r($customers); // All customers will have their phones eager loaded correctly, no loop needed!
Why Did the Loop Work?
When you loop through each customer and call $customer->phones, that's lazy loading. Laravel runs a separate query for each customer, filtering directly by that customer's ID. Since the query targets a single ID, it doesn't need the meta_value field in the select to map back — it just returns the matching phones. But eager loading batches all the phone queries at once, so it needs meta_value to pair each phone with its customer.
Bonus: Clean Up the Phone Model's Customer Relationship
You should add the meta_key condition here too to make the relationship more accurate:
/* Phone Model*/ namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Phone extends Model { use SoftDeletes; /** * Get the customer that owns the phone. */ public function customer(){ return $this->belongsTo('App\Customer', 'meta_value')->where('meta_key', 'customer'); } }
内容的提问来源于stack exchange,提问作者Sachin Kumar

