Reputation: 1163
Hello, in my scenario I'm trying to perform joins on 3 tables regarding a connections system I've built up. I'm able to use eloquent to connect these 3 tables together correctly and return the results no problem however, I'm trying to be more efficient in how it's done. I don't enjoy the fact that every query eloquent fires off defaults to a select *
so I'd like to select specific columns instead. Here's where I'm currently at:
Connection Controller Code
Groups::with([
'list.userAccount.profile'
])->where('user_id_fk', $my->user_id)
->orderBy('group_num', 'ASC')
->take(3)
->get(['group_num','group_title','group_id']);
Group Settings Model
public function list() {
return $this->hasMany('App\UserConnections','group_id_fk');
}
User Connections Model
public function userAccount() {
return $this->hasOne('App\User','user_id_fk');
}
User Account Model
public function profile() {
return $this->hasOne('App\Profile','user_id_fk');
}
Now, If I make a call to it's assigned route to get users an example result is the following:
{
"conn_id_fk": 2,
"user_id_fk": 10,
"type": 0,
"group_id_fk": 4,
"status": 1,
"created_at": "2017-02-09 13:58:34",
"updated_at": "2017-02-09 13:58:34",
"user_account": {
"user_id": 10,
"email": "[email protected]",
"verified": 0,
"locked": 0,
"code": 0,
"request": "",
"created_at": "2017-02-09 13:20:51",
"updated_at": "2017-02-09 13:20:51",
"profile": {
"user_id_fk": 3,
"first_name": "Jillian",
"last_name": "Jacobs",
"avatar": "",
"age": 0,
"about_me": "",
"one_liner": "",
"inspire": "",
"created_at": "2017-02-09 13:18:32",
"updated_at": "2017-02-09 13:18:32"
}
}
Again My dilemma is that I don't want it to do select *
to get all that data, it's unnecessary and will eventually slow down my server and cost me more money on I/O alone.
I've tried doing something like the following for example:
public function profileEnd() {
return $this->hasOne('App\Profile','user_id_fk');
}
public function profile() {
return $this->profileEnd->select('first_name','last_name','avatar');
}
///////////////////// AND I have tried///////////////////////////
public function profileEnd() {
return $this->hasOne('App\Profile','user_id_fk');
}
public function profile() {
return $this->profileEnd->select(['first_name','last_name','avatar'])->get(); <---Returns 500
}
which results in the following:
{
"conn_id_fk": 2,
"user_id_fk": 10,
"type": 0,
"group_id_fk": 4,
"status": 1,
"created_at": "2017-02-09 13:58:34",
"updated_at": "2017-02-09 13:58:34",
"user_account": {
"user_id": 10,
"email": "[email protected]",
"verified": 0,
"locked": 0,
"code": 0,
"request": "",
"created_at": "2017-02-09 13:20:51",
"updated_at": "2017-02-09 13:20:51",
"profile": null <------------------------------- Kills off the profile section
}
So What am I doing wrong here and how can I fix this? Any assistance is greatly appreciated. Thanks in advance Cheers!
Upvotes: 1
Views: 139
Reputation: 62248
Laravel needs the keys in order to match up the related collections of models. In your example, you did not select the key, so after the records are retrieved, Laravel has no idea which profiles are related to which user accounts. Add the key to the select and you should be good to go.
public function profileEnd() {
return $this->hasOne('App\Profile', 'user_id_fk');
}
public function profile() {
return $this->profileEnd->select('user_id_fk', 'first_name', 'last_name', 'avatar');
}
Upvotes: 1