问题
I have these two model. This phone model is a common model which can be used to save and fetch the phone value for a user, customer, Employee and so on. So the meta_value is used to save the id of related model and meta_key is used to determine the model name relation.
/* Customer Model*/
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Customer extends Model {
/**
* Get the Phone List.
*/
public function phones(){
return $this->hasMany('App\Phone','meta_value', 'id')
->select('id as phone_id','contact_number as phone','contact_number','country_code','type','dial_code')
->where('meta_key','customer');
}
}
/* Phone Model*/
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Phone extends Model {
/**
* Get the customer that owns the phone.
*/
public function customer(){
return $this->belongsTo('App\Customer', 'meta_value');
}
}
I can't get the data of phones with customer data. It always returns
[relations:protected] => Array
(
[phones] => Illuminate\Database\Eloquent\Collection Object
(
[items:protected] => Array
(
)
)
)
In My controller I do the following code.
/*This is the case when I want to get the data for a single customer.*/
$customer = Customer::find('448')->with('phones')->get();
print_r($customer); // It will return all customers with no phones value.
$customer = Customer::find('448');
print_r($customer);die; // It will return a single customer whose id is 448 with no phones value.
print_r($customer->phones);die; // I can get the values of phones by this
$customer = Customer::find('448')->with('phones');
print_r($customer);die; // It will crash my postman when i hit this.
/*This is the case when I want to get the data for multiple customers.*/
$customers = Customer::where('id', '>', '447')->with('phones')->get();
print_r($customers);die; // It will return multiple customer with empty phones value.
// However when I iterate through the loop and get phones then I can get the phone value.
$customers = Customer::where('id', '>', '447')->get();
foreach ($customers as $customer) {
$customer->phones = $customer->phones;
}
print_r($customers);die;
Only the iteration is working but I think that is not a good solution. Even I try load function but not working.
回答1:
You have to select the required foreign key column meta_value
:
->select('id as phone_id','contact_number as phone','contact_number','country_code',
'type','dial_code','meta_value')
For a single customer you don't need eager loading:
$customer = Customer::find(448);
$phones = $customer->phones;
It also looks like you should use polymorphic relationships.
回答2:
Although I suspect that selecting the phone_id
as id
may have affected query from checking the relationship but a quick debug would be to remove this from the related function:
->select('id as phone_id','contact_number as phone','contact_number','country_code','type','dial_code')
->where('meta_key','customer');
And let the function phones
be simply,
public function phones(){
return $this->hasMany('App\Phone','meta_value', 'id');
}
~UPDATED~
Then, you need to use load
instead.
If you need to further do a check later on the relationship, then pass a callback to filter it:
$customer = Customer::find('448')->load(['phones' => function($query) {
$query->where('meta_key','customer');
}]);
Or:
$customer = Customer::with(['phones' => function($query) {
$query->where('meta_key','customer');
}])->find('448');
The initial problem is:
Using with
and get
on the result of the find
creates another instance of the model for a fresh query hence you'll only get all the records of customer. You can use the load
method, or if you'll use with
then you'll have to set the filter at the end of the query functions.
For better understanding please check Laravel documentation on Eager Loading
来源:https://stackoverflow.com/questions/50345552/with-function-not-working-to-load-has-many-relation-data-laravel-model-eloquent