Tangible Bytes

A Web Developer’s Blog

Laravel Validation using DatabaseRule

The Laravel database validation rules are more powerful and flexible than I realised at first.

Looking at the Available Validation Rules we can see that Exists and Unique both have the suffix (Database)

This is because the both implement the DatabaseRule trait which offers more power than might be expected.

While the Laravel documentation does hint at this functionality with a couple of examples it is well worth reading the Laravel API docs for this trait and even reviewing the source code.

These database rules are constructed with arguments providing the table and column names.

Once constructed we can chain on a number of additional constraints

where : Set a “where” constraint on the query

whereNot : Set a “where not” constraint on the query

whereNull : Set a “where null” constraint on the query

whereNotNull : Set a “where not null” constraint on the query

whereIn : Set a “where in” constraint on the query

whereNotIn : Set a “where not in” constraint on the query

withoutTrashed : Ignore soft deleted models during the existence check

onlyTrashed : Only include soft deleted models during the existence check

The best place to understand how to call these is the source code

In my case I have a multisite project where each article has a slug that has to be unique - but only for that site.

Each article has a site_id field which specifies the site the article is for.

My Validation rules

$request->validate([
    'slug' => ['required', 'string', 'max:255',
        Rule::unique('articles')
        ->where('site_id', $article->site_id)
        ->ignore($article->id),
    ],
    'title' => 'required|string|max:255',
    'synopsis' => 'required|string|max:1000',
    'published_at' => 'nullable|date',
]);

The where parameters can take a number of forms but to me the most readable option is just column name and column value.

The ingore section seems to me to be something that should be the default - it just says allow the new value to be the same as the old value for the same article.