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