phplaravellaravel-bladerelational-databaseone-to-many

Attempt to read property "name" on null and $book->category?->name result in one record show data and other record not shown this data(table filled)


I have this one to many problems with table of books and categories on my laravel project.

three data I insert two of which is had same category column value with the corresponding id of said categories.

before I insert third data it was fine, but after I insert third data it show:

Attempt to read property "name" on null

I tried $book->category?->name and resulted in two previous data had category name appear but not the third, is there something wrong with my code of relation or what?

localhost of database table - books

laravel books table blade - third record not show/null on category

Categories.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Models\Book;

class Categories extends Model
{
    use HasFactory;
    public function book(): HasMany
    {
        return $this->hasMany(Book::class, 'category');
    }
    protected $fillable = [
        'name',
    ];
}

Book.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
use App\Models\Rent;
use App\Models\Categories;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Book extends Model
{
    use HasFactory;
    public function categories(): belongsTo
    {
        return $this->belongsTo(Categories::class, 'id');
    }
    protected $fillable = [
        'book_code',
        'book_title',
        'author',
        'category',
        'publisher',
        'stock',
        'book_cover',
        'book_desc',
        'barcode',
    ];
}

book/index.blade.php

@foreach ($book as $book)
    <tr>
        <td><img src="/{{ $book->book_cover }}" width="100px"></td>
        <td>{{ $book->book_title }}</td>
        <td>{{ $book->categories?->name }}</td>
        <td>{{ $book->stock }}</td>
        <td>
            <form action="{{ route('book.destroy',$book->id) }}" method="Post">
            <a class="btn btn-success" href="{{ route('book.show',$book->id) }}">Detail</a>    
            <a class="btn btn-warning" href="{{ route('book.edit',$book->id) }}">Edit</a>
                @csrf
                @method('DELETE')
                <button type="submit" class="btn btn-danger">Hapus</button>
            </form>
        </td>
    </tr>
@endforeach

Is there something wrong with my code that resulted in category name record shown on first and second record of book insert but not third record of book?


Solution

  • Always name the Model name as a singular name so it should be Category not Categories.

    Can you please try this function in your model?

    Category.php

    public function books() 
    {       
        return $this->hasMany(Category::class,'id');
     }
    

    Book.php

    public function categories()
    {
        return $this->belongsTo(Book :: class,'category','id');
    }