Implementing Dynamic Schemas in Laravel

M. Najmul
3 min readJun 26, 2024

--

Understanding Prerequisites

Before diving deeper into dynamic schemas, it’s essential to understand the following concepts:

  1. Laravel Migrations: How migrations work and how to create and modify tables. https://laravel.com/docs/10.x/migrations
  2. Eloquent Models: Basics of Eloquent ORM for interacting with the database. https://laravel.com/docs/10.x/eloquent
  3. JSON Handling: Storing and retrieving JSON data in Laravel. https://laravel.com/docs/10.x/eloquent-mutators#array-and-json-casting

What is a Schema?

Think of a schema as the blueprint for your database. Just like a blueprint for a house specifies where the rooms, doors, and windows go, a schema specifies the tables, columns, and relationships in your database.

Static vs. Dynamic Schema

Static Schema: Imagine you build a house based on a fixed blueprint. Once the house is built, making changes (like moving a wall) is difficult and requires a lot of effort. This is like having a fixed schema in your database. The structure is predefined, and making changes requires running migrations and manually altering the schema.

Dynamic Schema: Now imagine you have a magical house where you can move walls, add rooms, and change layouts instantly with a few commands. This is what a dynamic schema offers for a database. You can adjust the structure on-the-fly without predefined blueprints.

Why Use Dynamic Schemas?

  1. Flexibility: Allows your application to adapt to changing requirements without needing to redeploy or run migrations.
  2. User-Customizable Structures: Useful for applications where users can define their own data structures, like custom forms or content management systems.
  3. Efficient Development: Speeds up the development process by removing the need for frequent schema migrations.

To implement a dynamic schema in Laravel, we can use a combination of Eloquent models, migrations, and some runtime schema manipulation techniques.

Example: Creating a Dynamic Table

Let’s walk through an example where we create a dynamic table based on user input.

User Input for Table Structure: First, we gather input from the user about the structure of the table they want to create.

// Example input from the user
$tableName = 'user_profiles';
$columns = [
'first_name' => 'string',
'last_name' => 'string',
'age' => 'integer',
'email' => 'string'
];

Schema Builder: Use Laravel’s Schema Builder to create a table based on this input. This code will dynamically create a table named user_profiles with the columns specified by the user.

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;

Schema::create($tableName, function (Blueprint $table) use ($columns) {
$table->id(); // Add an id column

foreach ($columns as $name => $type) {
$table->{$type}($name);
}

$table->timestamps(); // Add created_at and updated_at columns
});

Example: Modifying an Existing Table

If we need to modify an existing table, we can do so using the Schema Builder’s table method. This will add the phone_number and address columns to the user_profiles table, allowing for runtime schema modification.

$columnsToAdd = [
'phone_number' => 'string',
'address' => 'text'
];

Schema::table('user_profiles', function (Blueprint $table) use ($columnsToAdd) {
foreach ($columnsToAdd as $name => $type) {
$table->{$type}($name)->nullable();
}
});

Advanced Techniques

Storing Schema Definitions

For more complex applications, you might want to store schema definitions in the database itself. This allows you to keep track of user-defined structures and make it easier to manage dynamic schemas.

Schema Definition Table: Create a table to store schema definitions.

Schema::create('table_definitions', function (Blueprint $table) {
$table->id();
$table->string('table_name');
$table->json('columns'); // Store column definitions as JSON
$table->timestamps();
});

Retrieving and Applying Schema: When you need to create or modify a table, retrieve the schema definition and apply it using the Schema Builder.

use App\Models\TableDefinition;

$tableDefinition = TableDefinition::where('table_name', 'user_profiles')->first();

if ($tableDefinition) {
$columns = json_decode($tableDefinition->columns, true);

Schema::create($tableDefinition->table_name, function (Blueprint $table) use ($columns) {
$table->id();

foreach ($columns as $name => $type) {
$table->{$type}($name);
}

$table->timestamps();
});
}

Dynamic schemas in Laravel provide powerful flexibility, allowing your application to adapt its database structure at runtime based on user input or other dynamic factors. This approach involves:

  • Gathering user input for table and column definitions.
  • Using Laravel’s Schema Builder to create or modify tables based on this input.
  • Optionally storing schema definitions in a database for more complex management.

Follow me on linked In

https://www.linkedin.com/in/md-najmul-mollah-41920ab9/

--

--

M. Najmul

Senior Software Engineer, Next Ventures | Problem Solver