I’m having a little bit of trouble figuring out the table structure and defining the relationships between the models for a category system and was wondering if someone could give me some advice. Basically I don’t want parent categories to be able to share child categories and posts between other parent categories and would like my URL structure to look like this:
Index of posts that fall under parent category (even of all the parent categories children):
example.com/parent_cat/
or
example.com/videos
Index of all posts in a child category of a parent category:
example.com/parent_cat/child_cat
or
example.com/videos/scifi/
How I want the singe post to render even after being clicked from a child category:
example.com/parent_cat/a-single-post
or
example.com/videos/starwars
I’m thinking I would use a table to hold the cat_id, post_id and site_id called child_parent_post like this(I think this is a polymorphic structure):
Schema::create('posts', function(Blueprint $table)
{
$table->increments('id');
$table->string('title');
$table->string('body');
$table->string('excerpt')->nullable();
$table->timestamps();
$table->timestamp('published_at');
});
Schema::create('parent_cats', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('slug');
$table->timestamps();
});
Schema::create('child_cats', function(Blueprint $table)
{
$table->increments('id');
$table->integer('parent_cat_id')->unsigned();
$table->string('name');
$table->string('slug');
$table->timestamps();
$table->foreign('parent_cat_id')->references('id')->on('parent_cat')->onDelete('cascade');
});
Schema::create('child_parent_post', function(Blueprint $table)
{
$table->integer('post_id')->unsigned()->index();
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->integer('parent_cat_id')->unsigned()->index();
$table->foreign('parent_cat_id')->references('id')->on('parent_cats')->onDelete('cascade');
$table->timestamps();
$table->integer('child_cat_id')->unsigned()->index();
$table->foreign('child_cat_id')->references('id')->on('child_cats')->onDelete('cascade');
$table->timestamps();
});
Here are my models:
class Post
{
/**
* A post can have one parent category
*
* @return $post->parentCategory;
*/
public function parentCategory()
{
return $this->belongsTo('App\ParentCatategoy');
}
/**
* A post can have one child category
*
* @return $post->childCategory;
*/
public function childCategory()
{
return $this->belongsTo('App\ChildCatategoy');
}
}
class ParentCategory
{
/**
* A parent category has many child categories
*
* @return $parentCategory->childCategories;
*/
public function childCategories()
{
return $this->hasMany('App\ParentCatategoy');
}
/**
* A parent category has many posts
*
* @return $parentCategory->posts;
*/
public function posts()
{
return $this->hasMany('App\Posts');
}
}
class ChildCategory
{
/**
* A ChildCategory can have one ParentCategoy
*
* @return $childCategory->parentCategory;
*/
public function parentCategory()
{
return $this->belongsTo('App\ParentCatategoy');
}
/**
* A child category has many posts
*
* @return $parentCategory->childCategory->posts;
*/
public function posts()
{
return $this->hasMany('App\Posts');
}
}
Sorry I tried hunting around for good advice, but the advice always had a different structure than I wanted. Should I use this model, or an adjacency list model? Am I even doing this right? I'm pretty confused.