Refactoring Rates: From Foreign Keys to Enums in Reimpact Platform

In the Reimpact platform, we're constantly striving for a cleaner, more maintainable codebase. Recently, we tackled an area involving rates and their association with different modules within the system.

The Problem: Priority Products and Foreign Keys

Originally, rates were tied to "priority products" using a foreign key relationship. This approach, while seemingly straightforward, introduced unnecessary complexity. The core issue was that "priority products" were essentially acting as schema prefixes, and the foreign key relationship enforced an inflexible structure.

The Solution: Embracing Enums for Module Definition

To address this, we opted for a more streamlined and explicit approach: replacing the priority_product_id foreign key with a module enum. Here's how we did it:

  1. Database Migration: The migration involved dropping the priority_product_id column and adding a module column. The module column defaults to packaging.

    Schema::table('rates', function (Blueprint $table) {
        $table->dropForeign(['priority_product_id']);
        $table->dropColumn('priority_product_id');
        $table->string('module')->default('packaging');
    });
    
  2. Enum Implementation: A FeatureEnum was created to define the possible values for the module column. This ensures type safety and provides a clear list of valid module options.

    enum FeatureEnum: string
    {
        case PACKAGING = 'packaging';
        case SHIPPING = 'shipping';
        case BILLING = 'billing';
    }
    
  3. Code Cleanup: We removed all references to priority_product_id in the seeders, Rate model, factory, and import jobs.

  4. Filament Integration: The RateResource in Filament was updated to use a select field for the module, allowing administrators to easily choose the appropriate module for each rate. A filter was also added for easy filtering.

    Select::make('module')
        ->options(FeatureEnum::class)
        ->searchable()
        ->required(),
    

The Benefits

  • Simplified Schema: Removing the foreign key constraint simplified the database schema and eliminated an unnecessary dependency.
  • Increased Flexibility: Using an enum allows for easier addition of new modules without requiring database schema changes.
  • Improved Code Clarity: The code became more explicit and easier to understand, as the relationship between rates and modules is now clearly defined by the module column.

The Takeaway

Don't be afraid to re-evaluate existing database relationships. Sometimes, seemingly straightforward foreign key relationships can introduce unnecessary complexity. Consider using enums or other more explicit approaches to improve schema clarity and flexibility, especially when dealing with categorical data. Take a look at your project and identify areas where foreign keys might be replaced with enums for a cleaner and more maintainable design.

Refactoring Rates: From Foreign Keys to Enums in Reimpact Platform
GERARDO RUIZ

GERARDO RUIZ

Author

Share: