Home > Back-end >  Laravel 8.6 firstOrCreate on variable model from URL
Laravel 8.6 firstOrCreate on variable model from URL

Time:05-25

In a URL i pass the table name with the where parameters en map this using a JSON. The problem is now is. I use DB::table($table) but this doesn't allow firstOrCreate so i wanted to try it by model, but $table::were doesn't see $table as a model name. Even if i change it from 'establisments' to 'Estalishment'. Maybe i need to put App\ before it? Because the model is not in use. How can i get the object using a model from model names as in the URL?

URL:

&spec_code=CHI&department=surgery&department_code=SUR

JSON:

{
  "establishments": { // $table name, but want it to be model)
    "from1": "spec_code", // from url
    "to1": "abc_id" // to column in database
  },
  "departments": {
    "from1": "department",
    "to1": "name",
    "from2": "department_code",
    "to2": "abc_id"
  },
}

Controller:

foreach(JSON as $table => $field){
if(isset($field['from2'])){
       $output[$table] = DB::table($table)->where($field['to1'], $request->input($field['from1']))->where($field['to2'], $request->input($field['from2']))->first();
}elseif(isset($field['from1'])){
       $output[$table] = DB::table($table)->where($field['to1'], $request->input($field['from1']))->first();
//     $output[$table] = $table::where($field['to1'], $request->input($field['from1']))->firstOrCreate(); //i want this.
//     $output[$table] = "\App\\".$table::where($field['to1'], $request->input($field['from1']))->firstOrCreate();
}else{
      $output[$table] = null;
}
}

If someone knows how i can get it to use the model so i can firstOrCreate(), that would make my code a lot cleaner.

Kind regards, Jeff

CodePudding user response:

There are many ways to do this. Create an array using which you can get model

$models = [
  'establishments' => \App\Models\Establishment::class,
  'departments' => \App\Models\Department::class,
]

Then within loop you can get the model from the array using

foreach(JSON as $table => $field){
   $models[$table]::firstOrCreate(/* */)
}

As i said there are many ways to fulfill your requirement. this is one way i would do.

CodePudding user response:

By Default laravel does't have out of the box method to get the Model FQN based on the table name.

Because you can have model under different namespace.

But however you can do a workaround

$tableClassToFind = 'users';
    $models = [
        \App\Models\User::class,
        //add your model(s) here
    ];

   $modelClass =  collect($models)
    ->map(function($eachModelFqn){
        return [
            'modelClass' => $eachModelFqn,
            'tableName' => app($eachModelFqn)->getTable(),
        ];
    })
    ->mapWithKeys(fn($value) => [$value['tableName'] => $value['modelClass']])
    ->get($tableClassToFind);

    dd($modelClass);

Basically it will get all the table name along with the Model FQN and changing the value of $tableClassToFind will get the appropriate Model class.

Please all the models to $models variable.

  • Related