Check if key exists in eloquent model

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

Answers (1)

D1__1
D1__1

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

Related Questions