October 26, 2024
Chicago 12, Melborne City, USA
PHP

Laravel: Retrieving records with string ids breaks app


I have a Laravel app which serves as a backend API. I changed the ids from ints to strings in the comments table, so I could add some abbreviations to the id based on the model it belongs to. Meaning instead of a comment-row getting an id of 5 it gets an id of CMT-45876348.

But after making this change, my app has started to break. When I hit the pagination endpoint (which worked before), the logs in my Laravel terminal show outputs like these:

# PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 40960 bytes) in \vendor\laravel\framework\src\Illuminate\Collections\Collection.php on line 1445
  PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 65536 bytes) in \vendor\composer\ClassLoader.php on line 576

or a different error message about the responsetime being too long.

I wanted to make sure it was because of these ids. So I kept all of the code the same but left the comments table empty and the app worked as normal. So I want to know how a simple id change can break that entire section of the app.

comments migration:

Schema::create('comments', function (Blueprint $table) { 
    $table->id(); 
    $table->foreignId('parent_id')->nullable()->constrained('comments')->onDelete('cascade'); 

    $table->string('id')->primary();

    $table->string('parent_id')->nullable();
    $table->foreign('parent_id')->references('id')->on('comments')->onDelete('cascade');

    $table->foreignId('user_id')->nullable()->constrained()->onDelete('cascade');
    $table->foreignId('post_id')->constrained()->onDelete('cascade');
    $table->longText('content');

Comment model:

class Comment extends Model { 
    use HasFactory, softDeletes;
    
    protected $primaryKey = 'id';
    public $incrementing = false;
    
    protected static function boot()
    {
        parent::boot();
    
        static::creating(function ($comment) {
            if (empty($comment->id)) {
                $comment->id = IdGenerator::generate('comment');
            }
        });
    }

Class used to generate the IDs:

class IdGenerator {

    public static function generate(string $modelType): string
    {
        $prefix = self::getModelPrefix($modelType);
    
        $timestamp = round(microtime(true) * 1000);
    
        return $prefix . '-' . $timestamp;
    }
    
    /**
     * Returns the model prefix based on the model type.
     *
     * @param  string  $modelType
     * @return string
     */
    private static function getModelPrefix(string $modelType): string
    {
        $modelPrefixMap = [
            'user' => 'USR',
            'post' => 'PST',
            'comment' => 'CMT',
            'like' => 'LIK',
            'tag' => 'TAG',
        ];
    
        return $modelPrefixMap[$modelType] ?? 'GEN';
    }
}



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video