Call Laravel model by string
Yes, you can do this, but you need to use the fully qualified class name:
$model_name = 'App\Model\User';
$model_name::where('id', $id)->first();
If your model name is stored in something other than a plain variable (e.g. a object attribute), you will need to use an intermediate variable in order to get this to work.
$model = $this->model_name;
$model::where('id', $id)->first();
This method should work well:
private function getNamespace($model){
$dirs = glob('../app/Models/*/*');
return array_map(function ($dir) use ($model) {
if (strpos($dir, $model)) {
return ucfirst(str_replace(
'/',
'\\',
str_replace(['../', '.php'], '', $dir)
));
}
}, array_filter($dirs, function ($dir) use ($model) {
return strpos($dir, $model);
}));
}
My project has multiple subdirectory and this function work well. So I recover the namespace of the model with $model = current($this->getNamespace($this->request->get('model')));
Then I just have to call my query: $model::all()
Try this:
$model_name = 'User';
$model = app("App\Model\{$model_name}");
$model->where('id', $id)->first();
if you use it in many of the places use this function
function convertVariableToModelName($modelName='',$nameSpace='App')
{
if (empty($nameSpace) || is_null($nameSpace) || $nameSpace === "")
{
$modelNameWithNameSpace = "App".'\\'.$modelName;
return app($modelNameWithNameSpace);
}
if (is_array($nameSpace))
{
$nameSpace = implode('\\', $nameSpace);
$modelNameWithNameSpace = $nameSpace.'\\'.$modelName;
return app($modelNameWithNameSpace);
}elseif (!is_array($nameSpace))
{
$modelNameWithNameSpace = $nameSpace.'\\'.$modelName;
return app($modelNameWithNameSpace);
}
}
Example if you want to get all the user
Scenario 1:
$userModel= convertVariableToModelName('User');
$result = $userModel::all();
Scenario 2:
if your model in in custom namespace may be App\Models
$userModel= convertVariableToModelName('User',['App','Models']);
$result = $userModel::all();
Hope it helps