Skip to content

Add support for external validation attribute references #1051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

rubenvanassche
Copy link
Member

Adds two new methods to inject values into validation attributes:

Docs

Referencing the current authenticated user

If you need to reference the current authenticated user in your validation attributes, you can use the
AuthenticatedUserReference:

use Spatie\LaravelData\Support\Validation\References\AuthenticatedUserReference;

class UserData extends Data
{
    public function __construct(
        public string $name,
        #[Unique('users', 'email', ignore: new AuthenticatedUserReference())]
        public string $email,
    ) {   
    }
}

When you need to reference a specific property of the authenticated user, you can do so like this:

class SongData extends Data
{
    public function __construct(
        #[Max(new AuthenticatedUserReference('max_song_title_length'))]
        public string $title,
    ) {
    }
}

Using a different guard than the default one can be done by passing the guard name to the constructor:

class UserData extends Data
{
    public function __construct(
        public string $name,
        #[Unique('users', 'email', ignore: new AuthenticatedUserReference(guard: 'api'))]
        public string $email,
    ) {   
    }
}

Referencing container dependencies

If you need to reference a container dependency in your validation attributes, you can use the ContainerReference:

use Spatie\LaravelData\Support\Validation\References\ContainerReference;

class SongData extends Data
{
    public function __construct(
        public string $title,
        #[Max(new ContainerReference('max_song_title_length'))]
        public string $artist,
    ) {
    }
}

It might be more useful to use a property of the container dependency, which can be done like this:

class SongData extends Data
{
    public function __construct(
        public string $title,
        #[Max(new ContainerReference(SongSettings::class, 'max_song_title_length'))]
        public string $artist,
    ) {
    }
}

When your dependency requires specific parameters, you can pass them along:

class SongData extends Data
{
    public function __construct(
        public string $title,
        #[Max(new ContainerReference(SongSettings::class, 'max_song_title_length', parameters: ['repository' => 'redis']))]
        public string $artist,
    ) {
    }
}

Headsup

Some internal changes were made to make this work, while technically not exposed to the outside for anyone to use, you're technically able to do so.

  • All validation attributes with RouteParameterReference as parameter now accept ExternalReference (RouteParameterReference is a ExternalReference)
  • The normalizePossibleRouteReferenceParameter in an ObjectValidationAttribute has been renamed to normalizePossibleExternalReferenceParameter
  • RouteParameterReference was Stringable, we've removed this interface since it wasn't used by the package and it makes things rather unclear where the value of a RouteParameterReference is called. You can continue using the getValue method which does the same.

@rubenvanassche rubenvanassche merged commit 6b110d2 into main Jun 25, 2025
36 checks passed
@rubenvanassche rubenvanassche deleted the feature/external-validation-attribute-references branch June 25, 2025 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant