идентификатор родителя для категории и подкатегории

#php #laravel #crud #laravel-models

Вопрос:

Я использую L8 ,И у меня есть category таблица, в ней есть parent_id мои подкатегории

categories table

Category model

categoryController

SubCategoryController

categories.blade

sub_categories.blade

В моем subcategory-index.blade.php я хочу показать категории, но я просто могу показать их с их идентификатором (идентификатор родителя).

Я не знаю, как показать название категорий вместо их идентификатора.

У меня есть эта таблица миграции для категорий :

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

        });
    }

 

и это моя модель категории :

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

 

И мой контроллер подкатегорий :

 ...

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'));
    }
...

 

И часть для показа заголовка подкатегории в 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>
 

Спасибо, что сказали мне, что делать :>

Комментарии:

1. В контроллере вашей подкатегории вы передаете parent_id как отношение, и такой связи нет. И ваши категории действуют как подкатегории, верно?

2. мой родитель-категория , а ребенок-подкатегория, и у меня есть 2 столбца идентификаторов , один из которых в первичном ключе (основной идентификатор), а другой-parent_id , когда категория имеет идентификатор parent_id со значением 123, это родитель, а когда категория parent_id имеет идентификатор других категорий, ее подкатегория. я надеюсь, вы понимаете. @МАЙ

3. Хорошо, я понимаю, если parent_id существует, то это подкатегория, Чтобы получить все основные или родительские категории, просто сделайте $categories = Category::whereNull('parent_id')->get();

4. для подкатегорий $sub_catgories = Categories::with('childern')->whereNotNull('parent_id')->get(); вам следует переименовать свое отношение, хотя оно должно быть родительским, а не дочерним, потому что оно указывает на родителя.

5. спасибо, но как я использую в blade? потому что у меня есть подкатегория для каждого и отображаются значения подкатегорий , а в подкатегории для каждого я хочу показать название категории. @МАЙ

Ответ №1:

Чтобы получить подкатегории

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

Чтобы получить подкатегории с родителем

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

Для извлечения категорий

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

Чтобы выбрать категории с детьми

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

Возможно, вам также придется пересмотреть свои отношения:

 public function parent()
{
    return $this->belongsTo(Category::class);
}

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

В миграции также определите отношение

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

Сделайте родительское поле обнуляемым

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

Комментарии:

1. большое вам спасибо .. у меня не было родительского отношения и внешнего ключа для parent_id , я добавил их, и это исправлено.

Ответ №2:

Строка ниже неверна. Потому что с() используется для получения реляционных данных, а parent_id не является именем отношения.

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

Если ваш маршрут содержит идентификатор или фрагмент категории, вы можете использовать его, но я думаю, что это не так, потому что ваша функция индекса не принимает никаких параметров маршрута. Поэтому я предполагаю, что вы пытаетесь выбрать все категории и подкатегории. Но в этом случае вторая строка индексной функции вообще не имеет смысла.

Если вы хотите, чтобы все категории:

 $categories = Category::where('parent_id', null)->with('children')->get();
 

Я вижу, что вы используете 123 для категорий верхнего уровня, и это выглядит достаточно высоко. Но аннулирование-лучшая практика для этой цели.

Если вам нужна конкретная категория и ее подкатегории:

 // web.php
Route::get('category/{slug}', [CategoryController::class, 'index']);

// CategoryConteroller.php
public function index($slug)
{
    $category = Category::where('slug', $slug)->with('children')->get();
}