Est-il possible d'appeler un modèle Laravel par chaîne?
C’est ce que j’essaie d’atteindre mais son échec:
$model_name = 'User';
$model_name::where('id', $id)->first();
Je reçois l'exception suivante:
exception 'ErrorException' with message 'Undefined variable: User'
Oui, vous pouvez le faire, mais vous devez utiliser le nom de classe complet:
$model_name = 'App\Model\User';
$model_name::where('id', $id)->first();
Si votre nom de modèle est stocké dans autre chose qu'une variable simple (par exemple, un attribut d'objet), vous devrez utiliser une variable intermédiaire pour que cela fonctionne.
$model = $this->model_name;
$model::where('id', $id)->first();
Essaye ça:
$model_name = 'User';
$model = app("App\Model\{$model_name}");
$model->where('id', $id)->first();
si vous l'utilisez dans de nombreux endroits, utilisez cette fonction
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);
}
}
Exemple si vous voulez obtenir tous les utilisateurs
Scénario 1:
$userModel= convertVariableToModelName('User');
$result = $userModel::all();
Scénario 2:
si votre modèle dans l'espace de noms personnalisé peut être App\Models
$userModel= convertVariableToModelName('User',['App','Models']);
$result = $userModel::all();
J'espère que ça aide
Oui, vous pouvez le faire avec plus de souplesse. Créer une fonction commune.
function getWhere($yourModel, $select, $is_model_full_path=null, $condition_arr=null)
{
if(!$is_model_full_path){ // if your model exist in App directory
$yourModel ="App\\$yourModel";
}
if(!$condition_arr){
return $yourModel::all($select)->toArray();
}
return $App_models_yourModel::all($select)->where($condition_arr)->toArray();
}
Vous pouvez maintenant appeler cette méthode de différentes manières.
getWhere('User', ['id', 'name']); // with default path of model
getWhere('App\Models\User', ['id', 'name'], true); // with custom path of model
getWhere('User', ['id', 'name'], false, ['id', 1]); // with condition array
Au fait, j'aime utiliser de telles fonctions.
Cette méthode devrait bien fonctionner:
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);
}));
}
Mon projet a plusieurs sous-répertoires et cette fonction fonctionne bien. Donc, je récupère l'espace de noms du modèle avec $model = current($this->getNamespace($this->request->get('model')));
Ensuite, il me suffit d'appeler ma requête: $model::all()