I have this category table, and I want to display the main categories and subcategories on the front end, that's the idea.
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('title', 2048);
$table->string('slug', 2048);
$table->unsignedBigInteger('parent_id')->nullable();
$table->timestamps();
$table->foreign('parent_id')->references('id')->on('categories')->onDelete('cascade');
});
}
The parent_id column is a foreign key that references the id column of the same categories table. This indicates a hierarchical relationship between the categories, where a category can have a parent category.
This is my Category model:
class Category extends Model { use HasFactory;
protected $fillable = [
'title',
'slug',
'parent_id'
];
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class, 'category_post', 'category_id', 'post_id');
}
public function subCategory()
{
return $this->hasMany(Category::class, 'parent_id');
}
}
The subCategory() function defines the hasMany relationship between categories. This indicates that a category can have multiple subcategories. The second argument passed to the hasMany function is the parent_id column used to establish the hierarchical relationship.
And since I'm using Filament for Laravel 10, this is how I associate one category with another from the form:
return $form ->schema([ // Other form components... Select::make('parent_id') ->label('Parent Category') ->options(\App\Models\Category::pluck('title', 'id')->toArray()) ->nullable(), ]);
The Select::make('parent_id') method creates a selection field and specifies that the selected value will be saved in the parent_id field of the model.
The options() method is used to provide the available options in the selection field. In this case, \App\Models\Category::pluck('title', 'id')->toArray() is used to retrieve all categories and convert them into an array where the keys are the category IDs and the values are the category titles.
I think my problem starts from here because I don't know how to interact with categories and subcategories on the front end to display them correctly. I want a dropdown menu where the title corresponds to the main category, and if it has subcategories, they should be displayed. If not, nothing should happen. However, if there are some categories without subcategories, I expect that nothing else happens. Without further ado, this is what's happening in the controller:
public function index()
{
$posts = Post::query()
->where('active', '=', 1)
->where('published_at', '<', Carbon::now())
->orderBy('published_at', 'desc')
->with('categories')
->take(4)
->get();
$latestPost = $posts->shift();
$categories = Category::with('subCategory')
->get();
return view('home', compact('posts', 'latestPost', 'categories'));
}
A query is made in the Category model using the with('subCategory') method. This loads the subcategory relationships for each category. This way, all categories along with their respective subcategories are obtained. The results are stored in the $categories variable.
By using dd($categories) from my controller, I can see the data I need, I can see the categories and all the related subcategories, for example:
News
New Music
Upcoming Releases Reviews Video
Music Videos
Funny Shid I have this category table, and I want to display the main categories and subcategories on the front end, that's the idea.
public function up(): void { Schema::create('categories', function (Blueprint $table) { $table->id(); $table->string('title', 2048); $table->string('slug', 2048); $table->unsignedBigInteger('parent_id')->nullable(); $table->timestamps();
$table->foreign('parent_id')->references('id')->on('categories')->onDelete('cascade');
});
}
The parent_id column is a foreign key that references the id column of the same categories table. This indicates a hierarchical relationship between the categories, where a category can have a parent category.
This is my Category model:
class Category extends Model { use HasFactory;
protected $fillable = [
'title',
'slug',
'parent_id'
];
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class, 'category_post', 'category_id', 'post_id');
}
public function subCategory()
{
return $this->hasMany(Category::class, 'parent_id');
}
}
The subCategory() function defines the hasMany relationship between categories. This indicates that a category can have multiple subcategories. The second argument passed to the hasMany function is the parent_id column used to establish the hierarchical relationship.
And since I'm using Filament for Laravel 10, this is how I associate one category with another from the form:
return $form ->schema([ // Other form components... Select::make('parent_id') ->label('Parent Category') ->options(\App\Models\Category::pluck('title', 'id')->toArray()) ->nullable(), ]);
The Select::make('parent_id') method creates a selection field and specifies that the selected value will be saved in the parent_id field of the model.
The options() method is used to provide the available options in the selection field. In this case, \App\Models\Category::pluck('title', 'id')->toArray() is used to retrieve all categories and convert them into an array where the keys are the category IDs and the values are the category titles.
I think my problem starts from here because I don't know how to interact with categories and subcategories on the front end to display them correctly. I want a dropdown menu where the title corresponds to the main category, and if it has subcategories, they should be displayed. If not, nothing should happen. However, if there are some categories without subcategories, I expect that nothing else happens. Without further ado, this is what's happening in the controller:
public function index()
{
$posts = Post::query()
->where('active', '=', 1)
->where('published_at', '<', Carbon::now())
->orderBy('published_at', 'desc')
->with('categories')
->take(4)
->get();
$latestPost = $posts->shift();
$categories = Category::with('subCategory')
->get();
return view('home', compact('posts', 'latestPost', 'categories'));
}
A query is made in the Category model using the with('subCategory') method. This loads the subcategory relationships for each category. This way, all categories along with their respective subcategories are obtained. The results are stored in the $categories variable.
By using dd($categories) from my controller, I can see the data I need, I can see the categories and all the related subcategories, for example:
News
However, I'm facing some errors as I cannot visualize what I have in mind:
<div class="flex-col items-center justify-center w-full py-4" x-data="{ open: false }">
@foreach($categories as $category)
<a href="{{ route('by-category', $category) }}" @mouseenter="open = true" @mouseleave="open = false" class="text-black font-bold uppercase">
{{ $category->title }} <i :class="open ? 'fa-chevron-down': 'fa-chevron-up'" class="fas ml-2"></i>
</a>
<div :class="open ? 'block': 'hidden'" @mouseenter="open = true" @mouseleave="open = false" class="bg-black">
@foreach($categories->subCategory as $subCategory)
<a href="{{ route('by-category', $subCategory) }}" class="text-white text-lg transition ease-out hover:bg-gray-100 hover:text-black rounded py-2 px-4 mx-2">
{{ $subCategory->title }}
</a>
@endforeach
</div>
@endforeach
</div>
But it gives me the following error:
Property [subCategory] does not exist on this collection instance.
Where did I go wrong? And why can't I see what I see in the dd? What I want is to use a dropdown menu and display all existing subcategories for the categories. Note: I have posts associated with subcategories, but I don't have a main category associated with a subcategory. Could that be my error? I have posts that have assigned subcategories, but not a main category with a post. Thanks!
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community