Skip to content

Categorization System Examples

This document shows how to use the HasCategorizations trait to categorize products with different types of categories.

Where this lives

  • Trait: app/Traits/HasCategorizations.php
  • Models: app/Models/Category.php, app/Models/Categorizable.php, app/Models/Product.php
  • Admin (manage categories): https://stage-api.easyotc.com/admin (staging) or http://localhost:8000/admin (local) — requires OTC_ONE_ADMIN role per app/Enums/RoleEnum.php. See /access for the full URL list.

How to run

The examples below are PHP snippets meant to run inside a Laravel context (controllers, services, or php artisan tinker):

bash
# From the easy-otc-api repo root
php artisan tinker

How the System Works

The categorization system has two main components:

  1. Categories - The actual category hierarchy (e.g., "Pain Relief", "NSAIDs", "Tablet")
  2. Categorizables - The polymorphic pivot table that connects models to categories with a categorization type (e.g., "drug_class", "therapeutic_category", "dosage_form")

Using the HasCategorizations Trait

1. Add the trait to your model

php
use App\Traits\HasCategorizations;

class Product extends Model
{
    use HasFactory, Searchable, HasCategorizations;
    // ... rest of your model
}

2. Create Categories

Create the actual categories you want to use for categorization:

php
// Create categories
$nsaidsCategory = Category::create([
    'uuid' => Str::uuid(),
    'name' => 'NSAIDs',
    'description' => 'Non-steroidal anti-inflammatory drugs',
    'slug' => 'nsaids',
    'is_active' => true
]);

$painReliefCategory = Category::create([
    'uuid' => Str::uuid(),
    'name' => 'Pain Relief',
    'description' => 'Medications for pain management',
    'slug' => 'pain-relief',
    'is_active' => true
]);

3. Categorize Products

Now you can categorize products with different types:

php
$product = Product::find(1);

// Categorize by drug class
$product->attachCategory($nsaidsCategory->id, 'drug_class', [
    'sort_order' => 1,
    'metadata' => ['prescription_required' => false]
]);

// Categorize by therapeutic category
$product->attachCategory($painReliefCategory->id, 'therapeutic_category', [
    'sort_order' => 1,
    'metadata' => ['severity_level' => 'mild']
]);

Available Methods

Basic Categorization

php
// Attach a category
$product->attachCategory($categoryId, 'drug_class', ['sort_order' => 1]);

// Detach a category
$product->detachCategory($categoryId, 'drug_class');

// Assign categories (replace all categories of a type)
$product->assignCategories([1, 2, 3], 'drug_class', ['sort_order' => 1]);

// Check if product has a category
$product->hasCategory($categoryId, 'drug_class'); // returns boolean

Retrieving Categories

php
// Get all categories of a specific type
$drugClassCategories = $product->categoriesOfType('drug_class');

// Get all categories across all types
$allCategories = $product->categories;

// Get all categorizations (with pivot data)
$categorizations = $product->categorizations;

// Get all categorizable types available for this model
$types = $product->getCategorizableTypes(); // ['drug_class', 'therapeutic_category']

Querying Products by Categories

php
// Find products in specific categories
$products = Product::withCategories([1, 2, 3], 'drug_class')->get();

// Find products with a specific category type
$products = Product::withCategoryType('therapeutic_category')->get();

Real-World Example

Here's how you might categorize an Advil product:

php
// Create the product
$advil = Product::create([
    'name' => 'Advil 200mg Tablets',
    'description' => 'Ibuprofen pain reliever',
    // ... other fields
]);

// Get categories
$nsaidsCategory = Category::where('slug', 'nsaids')->first();
$painReliefCategory = Category::where('slug', 'pain-relief')->first();
$tabletCategory = Category::where('slug', 'tablet')->first();
$advilFamilyCategory = Category::where('slug', 'advil-family')->first();

// Categorize the product
$advil->attachCategory($nsaidsCategory->id, 'drug_class', [
    'sort_order' => 1,
    'metadata' => ['prescription_required' => false]
]);

$advil->attachCategory($painReliefCategory->id, 'therapeutic_category', [
    'sort_order' => 1,
    'metadata' => ['severity_level' => 'mild']
]);

$advil->attachCategory($tabletCategory->id, 'dosage_form', [
    'sort_order' => 1,
    'metadata' => ['coated' => true]
]);

$advil->attachCategory($advilFamilyCategory->id, 'brand_group', [
    'sort_order' => 1,
]);

Benefits of This System

  1. Flexible: You can create any number of categorization types
  2. Hierarchical: Categories can have parent-child relationships
  3. Metadata: Each categorization can have additional data
  4. Sortable: Categories can be ordered within each type
  5. Queryable: Easy to find products by any categorization type
  6. Extensible: Add new categorization types without changing the database structure

Common Categorizable Types for Pharmaceuticals

  • drug_class - Pharmacological classification
  • therapeutic_category - Medical use/condition
  • dosage_form - Physical form (tablet, liquid, etc.)
  • brand_group - Brand family grouping
  • strength - Dosage strength categories
  • age_group - Target age demographics
  • prescription_status - OTC vs prescription
  • storage_conditions - Refrigeration requirements