Eloquent Query always returns null for parent table using oneToOne relationship

1.7k views Asked by At

Parent Table

users
schema | 'id','email','pass'

Relationship

 public function profile()
    {
        return $this->hasOne('App\Profile','user_id');
    }

Other Table

profiles
schema | 'id','user_id'/*foreign key to users table */ ,'address','city'

Relationship

public function user()
    {
        return $this->belongsTo('App\User','id');
    }

I'm querying Profile model and would like it to eagerload with User model.

public function edit($id){
$profile = \App\Profile::with('user')->where('id','=',$id)->get();
                dd($profile);
}

So that I can load the profile of the user for editing, alongwith the details data from User model like email & pass etc.

This Returns a null relation for user ??

Also, in blade while acessing $profile->user->email gives error

Undefined property: Illuminate\Database\Eloquent\Collection::$user (View: C:\xampp\htdocs\laravel1\resources\views\profile\edit.blade.php)

Here is the dd() output http://bit.ly/1dA0R5p

It returns null with user relation which is what i suspect causes undefined propertyerror in blade.

Is this approach possible? Are my relations correct?

P.S. Earlier I had a vice-versa case while Querying User model and eagerload Profile model and that worked.
Snippet

 $users = \App\User::with('group','profile')->get(); //This was working
2

There are 2 answers

3
chanafdo On BEST ANSWER

You receive null for because your relation definition is wrong. Your profile model should be

public function user()
{
    return $this->belongsTo('App\User','user_id');
}

The error is because you are trying to get the user object from a collection.

Since you have used get() to retrieve data you are receiving a collection of profiles, not a single profile. If you want a single profile use the first() method instead of get(), else use it inside a loop.

@foreach ($profiles as $profile)
   {{ $profile->user->email }}
@endforeach
0
Roberto Belotti On

Remove use SoftDeletes; if this line is present in child Model.

namespace App;
use Illuminate\Database\Eloquent\Model;
//use Illuminate\Database\Eloquent\SoftDeletes;
use App\User;
class Profile extends Model
{
//    use SoftDeletes;

/**
 * The database table used by the model.
 *
 * @var string
 */
protected $table = 'profile';

/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = ['address', 'user_id'];

protected $primaryKey = 'user_id';

public function user() {
    return $this->belongsTo('App\User');
}    
}

And now set $primaryKey = 'user_id';

In oparent Model:

public function profile(){
    return $this->hasOne('App\Profile');
}

And so you can retrieve user profile

$profile = $user->profile? : new Profile;