Reputation: 3327
I am trying to create a helper function that checks if a specific key exists inside an eloquent model to generate a dynamic query that only checks for the correct keys.
I have made to helper functions like such:
if(!function_exists('entityHasKey')){
function entityHasKey(Model $eloquentModel, string $key): bool
{
return array_key_exists($key, $eloquentModel->getAttributes());
}
}
if(!function_exists('hasEntityKeys')){
/**
* @param string $eloquentModel
* @param string[] $keys
* @return bool
*/
function entityHasKeys(string $eloquentModel, array $keys): bool
{
$hasKey = false;
foreach($keys as $key){
if(entityHasKey($eloquentModel, $key)){
$hasKey = true;
break;
}
}
return $hasKey;
}
}
In my head, the logic makes good sense, but the issue is now that I can't pass the attributes from the class (without having an instance). My best guess would be the use the static class instance, but that only gets me the name.
What is the best approach to check if a key exists on an eloquent model (without an instance necessarily)
usage example
(*other conditions * and entityHasKeys(MyCoolModel::class, $filters['columns']))
Upvotes: 1
Views: 943
Reputation: 1357
The Schema
facade has a method called getColumnListing()
which takes the table name as a parameter. If you want to get all the columns that are present in the table (which are essentially the possible attributes) you can do something like this.
You may use the app()
helper to get the table name without an instance of the model.
use Illuminate\Support\Facades\Schema;
$attributes = Schema::getColumnListing(
app(\App\Models\User::class)->getTable()
);
You can then create a function that accepts an attribute name as a string or multiple attributes in an array that should be checked for, in combination with the model name as a string (e.g. User
).
function modelHasAttributes(string $model, string|array $attributes): bool
{
$attributes = is_array($attributes) ? $attributes : [$attributes];
$modelAttributes = Schema::getColumnListing(
app("\App\Models\\$model")->getTable()
);
return count(array_intersect($attributes, $modelAttributes)) === count($attributes);
}
This will yield you the following results (tested with default User
model).
modelHasAttributes('User', 'name'); // true
modelHasAttributes('User', 'nope'); // false
modelHasAttributes('User', ['id', 'name']); // true
modelHasAttributes('User', ['id', 'nope']); // false
Upvotes: 4