Search code examples
laravellaravel-7eloquent-relationship

Null Value On One-to-One Relationships Laravel 7


I have an One-to-One relationships Between the user (penggunas) table and the role table, but when I access it in the controller it returns null and column not found

Route.php

Route::get('/test', 'PenggunaController@index');

PenggunaController.php

use App\Pengguna;

class PenggunaController extends Controller
{
    public function index()
    {
        $pengguna = Pengguna::find(3);
        return response()->json([
            'data' => $pengguna
        ]);
    }
}

Migrations

create_penggunas_table

public function up()
{
    Schema::create('penggunas', function (Blueprint $table) {
        $table->id();
        $table->string('username');
        $table->unsignedBigInteger('role_id');

        $table->foreign('role_id')->references('id')->on('roles');
    });
}

create_roles_table

public function up()
{
    Schema::create('roles', function (Blueprint $table) {
        $table->id('id');
        $table->string('role_name')->unique();
    });
}

Model

Pengguna.php

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

Role.php

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

So, on the method index at PenggunaController.php I am fetching data which have id = 3. It's return full data, the role_id shows up, but if I access it like $pengguna_role = $pengguna->role->role_name;, it returns error with message column not found. Then I tried to change to $pengguna->roles->role_name;, it returns error with message 'not an object', I tried dd($penggunas->roles); and it's returning null.

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'roles.pengguna_id' in 'where clause' (SQL: select * from roles where roles.pengguna_id = 3 and roles.pengguna_id is not null limit 1)

roles table

penggunas table

I can get around this by taking the role_id in the result from User::find(3); and then Role::where('id', $pengguna->role_id);. But it makes me confused why I can't access it directly using relationship.


Solution

  • your relationship definition is wrong here. it got reverted. as user has role id, it should belong to Role class. you are using hasOne and laravel is looking for a pengguna_id in roles table but there's none. so you are getting null. change it like

    public function role() {
        return $this->belongsTo('App\Role', 'role_id');
    }
    

    and then you can access value like

    $pengguna_role = $pengguna->role->role_name;
    

    and i think, a role may have different users. so use hasMany in Role model

    public function penggunas() {
        return $this->hasMany('App\Pengguna', 'role_id');
    }