phplaravelcrudlaravel-models

parent id for category and subcategory


I use L8 And I have a category table ,it has parent_id for my subcategories

categories table

Category model

categoryController

SubCategoryController

categories.blade

sub_categories.blade

In my subcategory-index.blade.php I want to show categories but I just can show them with their id (parent id)

I don't know how to show categories title instead of their id.

I have this migration for categories table :

public function up()
    {

        Schema::dropIfExists('categories');
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('parent_id')->default(123);

            $table->string('title');
            $table->longText('description');
            $table->tinyInteger('status')->comment('status is 1 when a category is active and it is 0 otherwise.')->nullable();


            $table->rememberToken();
            $table->softDeletes();
            $table->timestamps();

        });
    }

and this is my category model :

class Category extends Model
{
    use HasFactory;

    protected $fillable = [
         'parent_id','title' , 'description', 'status',
    ];

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

    public function post(){
        return $this->hasMany(Post::class);
    }
}

And my subcategory controller :

...

public function index()
    {
        $parent_id = Category::with('parent_id')->get();
        $subcategories = Category::where('parent_id' ,'!=', 123)->get();
         return view('admin.subcategories.subcategories-index' , compact('subcategories'));
    }
...

And the part for show subcategory title in category-index.blade.php :

<table class="table table-bordered">
        <tr>
            <th>#</th>
            <th>id</th>
            <th>title</th>
            <th>category</th>
            <th>status</th>
            <th>operation</th>

        </tr>

        @foreach($subcategories as $subcategory )
        <tr>
            <td>{{ $loop->iteration }}</td>
           <td>{{ $subcategory['id'] }}</td>
           <td>{{ $subcategory['title'] }}</td>
           <td>{{ $subcategory['parent_id']}}</td>
           <td>
               @if($subcategory['status']==0 or $subcategory['status']==NULL)
                inactive
               @else
               active
               @endif
           </td>
           <td>
               <form method="POST" action="{{ route('subcategory.destroy',$subcategory->id) }}">
                   <a class="btn btn-info" href="{{ route('subcategory.show' , $subcategory->id) }}">show</a>
                   <a class="btn btn-primary" href="{{ route('subcategory.edit' , $subcategory->id) }}">edit</a>
                   @csrf
                   @method('DELETE')
                   <button type="submit" class="btn btn-danger"> delete</button>

               </form>
           </td>
        </tr>

        @endforeach

    </table>

Thanks for telling me what to do :>


Solution

  • To get subcategories

    $sub_categories = Category::whereNotNull('parent_id')->get();
    

    To get sub-categories with parent

    $sub_categories_with_parent = Category::with('parent')->whereNotNull('parent_id')->get();
    

    To fetch categories

    $categories = Category::whereNull('parent_id')->get();
    

    To fetch categories with children

    $categories_with_childern = Category::with('children')->whereNull('parent_id')->get();
    

    You might have to redefine your relations as well:

    public function parent()
    {
        return $this->belongsTo(Category::class);
    }
    
    public function children()
    {
        return $this->hasMany(Category::class , 'parent_id');
    }
    

    In migration define relation as well

    $table->foreign('parent_id')->references('id')->on('categories')->onUpdate('cascade')->onDelete('cascade');
    

    Make parent field nullable

    $table->unsignedBigInteger('parent_id')->nullable()->default(123);