laracraft-tech/laravel-dynamic-model
Installation:
composer require laracraft-tech/laravel-dynamic-model
Publish the config (if needed):
php artisan vendor:publish --provider="LaracraftTech\DynamicModel\DynamicModelServiceProvider"
Basic Usage:
Define a model extending DynamicModel:
use LaracraftTech\DynamicModel\DynamicModel;
class MultiTableModel extends DynamicModel
{
protected $table = null; // Will be set dynamically
}
First Use Case: Dynamically switch tables at runtime:
$model = new MultiTableModel();
$model->setTable('users'); // Switch to 'users' table
$user = $model->find(1); // Query 'users' table
config/dynamic-model.php (if published) for default behaviors.README.md for table-switching logic and query customization.tests/ directory for edge cases and examples.Dynamic Table Switching:
// Switch table dynamically
$model->setTable('products');
$product = $model->find(1);
// Or via constructor
$model = new MultiTableModel(['table' => 'orders']);
Multi-Database Support:
$model->setConnection('mysql_slave');
$model->setTable('analytics');
$data = $model->all();
Query Customization:
Override getTable() or getConnection():
class CustomModel extends DynamicModel
{
public function getTable()
{
return request()->input('table') ?? parent::getTable();
}
}
Polymorphic Relationships:
Use morphTo with dynamic models for flexible relationships:
class Post extends Model {
public function owner()
{
return $this->morphTo()->type('user')->model(MultiTableModel::class);
}
}
API Endpoints: Dynamically resolve tables based on route parameters:
Route::get('/data/{table}', function ($table) {
$model = new MultiTableModel();
$model->setTable($table);
return $model->all();
});
Caching: Cache table configurations if tables are static:
$model->setTable('cached_table');
$model->setConnection('cached_db');
Table Validation:
if (!Schema::hasTable($model->getTable())) {
throw new \InvalidArgumentException("Table {$model->getTable()} does not exist.");
}
Schema::hasTable() or DB::select("SHOW TABLES LIKE '$table'") for MySQL.Query Builder Conflicts:
// Disable global scopes temporarily
$model->withoutGlobalScopes(function () use ($model) {
return $model->where('active', 1)->get();
});
Mass Assignment:
$fillable is defined per table if needed:
protected $fillable = ['name', 'email']; // Default
public function setTable($table)
{
if ($table === 'admins') {
$this->fillable = ['username', 'role'];
}
return parent::setTable($table);
}
Log Table Switches: Add a trait to log table changes:
trait LogsTableSwitches
{
public function setTable($table)
{
\Log::debug("Switched table to: {$table}", ['model' => static::class]);
return parent::setTable($table);
}
}
Query Logging: Enable Laravel’s query logging:
DB::enableQueryLog();
$model->find(1);
\Log::debug(DB::getQueryLog());
Custom Table Resolution:
Override resolveTable() to implement logic like:
public function resolveTable($table = null)
{
return $table ?? config("dynamic-model.default_table");
}
Event Hooks:
Listen for model.setTable events (if supported in future versions) or use traits:
trait TableSwitchListener
{
public function setTable($table)
{
event(new TableSwitched($this, $table));
return parent::setTable($table);
}
}
Soft Deletes: Handle soft deletes per table:
public function getDeletedAtColumn()
{
return $this->getTable() === 'archived_users' ? 'deleted_at' : null;
}
config/dynamic-model.php:
'default_table' => 'default',
'default_connection' => null,
.env has multiple database connections configured:
DB_CONNECTION_mysql_slave=mysql
DB_HOST_mysql_slave=slave.example.com
How can I help you explore Laravel packages today?