Laravel 7 - belongsTo 关系 - 尝试获取非对象的 属性

Laravel 7 - belongsTo relation - Trying to get property of non-object

开始之前: 我已经看了“类似问题”的建议,虽然确实有很多类似问题的类似问题,但我还没有找到解决方案.我也是刚开始学Laravel几天,还请大家多多包涵

我使用的是最新的 Laravel 框架 (7.18.0)。我有三个 tables:

pirates
----------
pirate_id serial NOT NULL, -- PK
pirate_name character varying(200) NOT NULL,
beard_size integer NOT NULL,
beard_color integer NOT NULL,

beard_sizes
----------
beard_size_id serial NOT NULL, -- PK
beard_size character varying(100) NOT NULL

beard_colors
----------
beard_color_id serial NOT NULL, -- PK
beard_color character varying(100) NOT NULL

我使用 php artisan 命令生成模型并尝试定义模型:

Pirate.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Pirate extends Model
{
    public $timestamps = false;
    
    protected $primaryKey = 'pirate_id';
    
    protected $fillable = ['pirate_name', 'beard_size', 'beard_color'];
    
    public function beardSize()
    {
        return $this->belongsTo('App\BeardSize', 'beard_size_id');
    }
    
    public function beardColor()
    {
        return $this->belongsTo('App\BeardColor', 'beard_color_id');
    }
}

BeardSize.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class BeardSize extends Model
{
    public $timestamps = false;
    
    protected $primaryKey = 'beard_size_id';
    
    protected $fillable = ['beard_size'];
    
    public function pirates()
    {
        return $this->hasMany('App\Pirate', 'pirate_id');
    }
}

BeardColor.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class BeardColor extends Model
{
    public $timestamps = false;
    
    protected $primaryKey = 'beard_color_id';
    
    protected $fillable = ['beard_color'];
    
    public function pirates()
    {
        return $this->hasMany('App\Pirate', 'pirate_id');
    }
}

试图显示我的“海盗”table的数据,这是我的控制器:

PirateController.php

<?php

namespace App\Http\Controllers;

use App\Pirate;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PirateController extends Controller
{
    public function main()
    {
        $pirates = Pirate::paginate(4);
        
        return view('main', ['pirates' => $pirates]);
    }
}

这是我的观点:

main.blade.php

@extends('pirate')

@section('main_nav', 'This is our ship')

@section('main_content')

<p>List of our crew:</p>

<table class="table-view">
    <thead>
        <tr>
            <th style="width: 60px;">No.</th>
            <th>Name</th>
            <th style="width: 160px;">Beard size</th>
            <th style="width: 160px;">Beard color</th>
            <th>&nbsp;</th>
            <th>&nbsp;</th>
        </tr>
    </thead>
    <tbody>
        @foreach($pirates as $ind => $pirate)
        <tr>
            <td>{{ ($ind + 1) . '.' }}</td>
            <td>{{ $pirate->pirate_name }}</td>
            <td>{{ $pirate->beardSize->beard_size }}</td>
            <td>{{ $pirate->beardColor->beard_color }}</td>
            <td class="table-nav"><a href="update/{{$pirate->pirate_id}}">edit</a></td>
            <td class="table-nav"><a href="delete/{{$pirate->pirate_id}}">delete</a></td>
        </tr>
        @endforeach
    </tbody>
</table>

{{ $pirates->links() }}

@endsection

每次我尝试获取关系 table 的数据(beard_sizesbeard_colors)时,我都会遇到错误:Trying to get property 'beard_size' of non-objectTrying to get property 'beard_color' of non-object.作为记录,pirates table 中的 beard_sizebeard_color 列不为空。

关于数据库tables中的字段名,文档中提到主键应该如何写成id等,但是在我的下一个项目中,我已经使用了现有数据库超过 100 个 table,因此无法更改列的名称。

NOT NULL 可能不足以作为主键;将其设置为 UNSIGNEDBIGINT 并启用 AUTOINCREMENT。列的名称并不重要。我的意思是,通常可以简单地定义它的名称:protected $primaryKey = 'pirate_id'; ...正如您已经拥有的那样。

App\Pirateone-to-many关系应表示为:

嗯,实际上是 one-to-one ...因为 1 个海盗只有 1 个胡子。

public function beardSize()
{
    return $this->hasOne('App\BeardSize', 'beard_size_id');
}

public function beardColor()
{
    return $this->hasOne('App\BeardColor', 'beard_color_id');
}

根据您提供的架构,您需要具有以下关系:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Pirate extends Model
{
    public $timestamps = false;
    
    protected $primaryKey = 'pirate_id';
    
    protected $fillable = ['pirate_name', 'beard_size', 'beard_color'];
    
    public function beardSize()
    {
        return $this->belongsTo('App\BeardSize', 'beard_size', 'beard_size_id');
    }
    
    public function beardColor()
    {
        return $this->belongsTo('App\BeardColor', 'beard_color', 'beard_color_id');
    }
}

belongsTo 关系具有以下结构:

     return $this->belongsTo(Related::class, 'key_on_own_table', 'key_on_related_table');