Logarithmique's avatar

Indexable trait

Hi !, I'm currently dev an ecommerce app, everythings work great ( love Laravel ) , on a lot of model i put an Index column which is for display purpose only. I let the admin the possibility of reorder the display. For example if he want to show some product ahead of other etc, category. Is it bad practice ?

I also think about creating a indexeable table with morph many , and then create a trait on indexeable table ?

Thanks !

0 likes
3 replies
LaryAI's avatar
Level 58

Using an index column for display purposes in your models is a common practice and can be quite effective for allowing custom ordering of items, such as products in an e-commerce application. However, if you want to make this functionality more reusable and maintainable, creating a trait with a polymorphic relationship is a good approach. Here's how you can implement it:

  1. Create the Indexable Trait:

    This trait will handle the logic for ordering and reordering items.

  2. Add the index Column to Your Models:

    Ensure that your models have an index column in their respective tables. You can add this column using a migration:

    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    class AddIndexToYourModelTable extends Migration
    {
        public function up()
        {
            Schema::table('your_model_table', function (Blueprint $table) {
                $table->integer('index')->nullable();
            });
        }
    
        public function down()
        {
            Schema::table('your_model_table', function (Blueprint $table) {
                $table->dropColumn('index');
            });
        }
    }
    
  3. Use the Trait in Your Models:

    Apply the Indexable trait to any model that requires custom ordering.

    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    use App\Traits\Indexable;
    
    class Product extends Model
    {
        use Indexable;
    
        // Other model properties and methods
    }
    
  4. Reordering Logic:

    You can now use the reorder method to change the order of items, and the ordered scope to retrieve items in the desired order.

    $product = Product::find(1);
    $product->reorder(5); // Change the index to 5
    
    $orderedProducts = Product::ordered()->get(); // Get products ordered by index
    

By using a trait, you encapsulate the logic related to indexing and make it reusable across different models. This approach also keeps your codebase clean and adheres to the DRY (Don't Repeat Yourself) principle.

1 like
Tray2's avatar

Not a bad practice, but if you find that you do it in multiple tables, then pushing it to it's own table is the in my opinion the right way to go.

1 like
Snapey's avatar

personally, a single order column directly on the table is the better approach

1 like

Please or to participate in this conversation.