Changing primary key of a polymorphic 'comments' table from 'id' to a varchar, PHP runs out of memory
When I change the primary key of my polymorphic 'comments' table from 'id' to a varchar, PHP runs out of memory. How can I fix this?
This is my comments table schema. I would like every request (CRUD) to be based off of comment_hash instead of 'id'. Can this actually be accomplished?
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';
/**
* Customize the primary key for comment model. Results in 'out of memory'
*/
protected $primaryKey = 'comment_hash';
/**
* 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 which times out (this works perfectly and returns nested comments if dont change the Comments primary key from id to comment_hash, as seen above)
$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);
This is the error I see in the browser when I try to hit the API:
Error:
This page isn’t working
localhost is currently unable to handle this request.
HTTP ERROR 500
Error logs in terminal:
[Fri Sep 27 10:08:08 2019] PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 163840 bytes) in /Users/kp/kb_backend_apis_laravel/vendor/composer/ClassLoader.php on line 444
Can this actually be accomplished? if so, how?
Please or to participate in this conversation.