@lostdreamer_nl thanks....those approaches are interesting (parent-child vs nested set). This is what I have so far...based on your last suggestion. My application is going to be heavier on reads (versus writes/updates). Would you recommend any changes to this to speed things up?
I created a polymorphic 'comments' table as you suggested.
This is my comments table schema.
CREATE TABLE `comments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`comment_hash` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`body` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`commentable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`commentable_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `comment_user_hash_parentid_unique` (`user_id`,`comment_hash`,`commentable_id`),
KEY `comment_hash_index` (`comment_hash`),
CONSTRAINT `user_fk_369255` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2048 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
This is a snippet from my Comments.php model:
class Comment extends Model
{
use SoftDeletes;
public $table = 'comments';
/**
* Get the owning commentable model.
*/
public function commentable()
{
return $this->morphTo();
}
/**
* Get all of the comments (single-level, not recursively)
*/
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
/**
* Get all of the comments' comments recursively.
*/
public function nestedComments()
{
// Get comments recursively, from https://laraveldaily.com/eloquent-recursive-hasmany-relationship-with-unlimited-subcategories/
return $this->morphMany(Comment::class, 'commentable')->with('nestedComments');
}
And this is my API / Controller code:
$max_top_level_comments = 20;
$post =
Post::with([
'comments' => function ($query) use ($max_top_level_comments) {
$query
->where([
['is_removed', '=', '0'],
['deleted_at', '=', NULL],
])
->select('id', 'comment_hash', 'body', 'user_id', 'commentable_id', 'commentable_type', 'created_at')
->with([
'nestedComments' => function ($query) {
$query
->where([
['is_removed', '=', '0'],
['deleted_at', '=', NULL],
])
->select('id', 'comment_hash', 'body', 'user_id', 'commentable_id', 'commentable_type', 'created_at');
},
])
->take($max_top_level_comments)
->get();
},
])
->find(1);