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

Я новичок в Laravel и использую L8.

У меня есть таблица category, и в ней есть parent_id для моих подкатегорий.

Я использую одну таблицу и модель для CRUD, но мой контроллер и представление разделены.

это означает :

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>

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


person calisa    schedule 12.03.2021    source источник
comment
В вашем контроллере подкатегории вы передаете parent_id как отношение, а такого отношения нет. И ваши категории действуют как подкатегории, верно?   -  person MAY    schedule 12.03.2021
comment
мой родитель - это категория, а дочерний элемент - это подкатегория, и у меня есть 2 столбца идентификаторов, один из них в первичном ключе (основной идентификатор), а другой - parent_id, когда у категории есть parent_id со значением 123, это родительский элемент, а когда категория parent_id имеет другие категории, ID своей подкатегории. Надеюсь, ты понимаешь. @МАЯ   -  person calisa    schedule 12.03.2021
comment
Хорошо, я понял, если parent_id существует, то это sub_category, Чтобы получить все main_categories или parent_categories, просто выполните $categories = Category::whereNull('parent_id')->get();   -  person MAY    schedule 12.03.2021
comment
для подкатегорий $sub_catgories = Categories::with('childern')->whereNotNull('parent_id')->get(); вы должны переименовать свое отношение, оно должно быть parent, а не childern, потому что оно указывает на родителя.   -  person MAY    schedule 12.03.2021
comment
спасибо, но как я использую лезвие? потому что у меня есть подкатегория foreach и отображаются значения подкатегории, а в подкатегории foreach я хочу отображать заголовок категории. @МАЯ   -  person calisa    schedule 12.03.2021
comment
Глядя на отношение, определенное выше, вы можете иметь подкатегории с несколькими родителями, поэтому коллекция $ sub_categories, которую вы получите, будет иметь вложенную коллекцию родителей, вы можете зацикливаться на этой коллекции, чтобы получить имя родительской категории.   -  person MAY    schedule 12.03.2021
comment
спасибо @MAY за вашу помощь   -  person calisa    schedule 12.03.2021
comment
Рад был помочь :)   -  person MAY    schedule 12.03.2021
comment
извините за то, что вас раздражает, но теперь я помещаю $ sub_categories_with_parent в свой контроллер, и когда в моем клинке индекса я помещаю это {{ $subcategory->parent_id->title}}, дает мне Попытку получить свойство 'title' не-объектной ошибки. где моя ошибка?   -  person calisa    schedule 12.03.2021
comment
поскольку parent_id не является объектом, вы должны сделать это $parents = $sub_categories->parent, это даст вам всех родителей для этой подкатегории, поскольку из вашего отношения одна подкатегория может иметь несколько родителей. а затем зациклиться на $parents и получить доступ к заголовку с помощью $parent->title. Я надеюсь, это поможет.   -  person MAY    schedule 13.03.2021
comment
да, помогло, спасибо ^ _ ^   -  person calisa    schedule 13.03.2021


Ответы (2)


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

$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');

Сделать родительское поле допускающим значение NULL

$table->unsignedBigInteger('parent_id')->nullable()->default(123);
person MAY    schedule 12.03.2021
comment
Большое вам спасибо .. У меня не было родительского отношения и внешнего ключа для parent_id, я добавил их, и это исправлено. - person calisa; 12.03.2021

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

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

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

Если вы хотите для всех категорий:

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

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

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

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

// CategoryConteroller.php
public function index($slug)
{
    $category = Category::where('slug', $slug)->with('children')->get();
}
person Bulent    schedule 12.03.2021
comment
спасибо, я изменил его на nullable - person calisa; 12.03.2021