一对一关系的空值 Laravel 7

Null Value On One-to-One Relationships Laravel 7

我在用户 (penggunas) table 和角色 table 之间存在一对一关系,但是当我在控制器中访问它时,它 return 为空未找到列

Route.php

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

PenggunaController.php

使用App\Pengguna;

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

迁移

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();
    });
}

型号

Pengguna.php

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

Role.php

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

因此,在 PenggunaController.php 的方法索引上,我正在获取 id = 3 的数据。它是 return 完整数据, role_id 显示,但如果我访问它与 $pengguna_role = $pengguna->role->role_name; 一样,它 return 找不到消息列的错误。然后我尝试更改为 $pengguna->roles->role_name;,它 return 错误消息 'not an object',我尝试 dd($penggunas->roles); 并且它是 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)

我可以通过在 User::find(3);Role::where('id', $pengguna->role_id); 的结果中获取 role_id 来解决这个问题。但这让我很困惑为什么我不能直接使用关系访问它。

这里你的关系定义是错误的。它被恢复了。由于用户有角色 ID,它应该属于角色 class。您正在使用 hasOne,而 laravel 正在寻找角色 table 中的 pengguna_id,但有 none。所以你变得空了。改成

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

然后您可以访问像

这样的值
$pengguna_role = $pengguna->role->role_name;

而且我认为,一个角色可能有不同的用户。所以在角色模型中使用 hasMany

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