Skip to content

Conversation

@Klaas058
Copy link
Contributor

Currently when using annotations with database rules like Exists and Unique, it is not possible to include database constraints.

This will throw a php error:

// Error: Constant expression contains invalid operations
#[Exists(Customer::class, column: 'id', where: fn($query) => $query->where('active', true))]
public ?int $customer_id

This feature would allow using database constraints like so:

// Valid php 🎉
#[Exists(Customer::class, column: 'id', where: new WhereConstraint('active', true))]
public ?int $customer_id

After testing this has been working great for us, happy with any feedback

One thing I'm not a 100% sure about:

  • Types in the DatabaseConstraint implementations are mixed since the Laravel methods are untyped themselves. Is this the best way?

Copy link
Member

@rubenvanassche rubenvanassche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great, few changes required and then this one is good to go!

) {
}
}
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a list here with the possible constraints?

Comment on lines 59 to 72
$constraints = is_array($this->where) ? $this->where : [$this->where];

foreach ($constraints as $constraint) {
match (true) {
$constraint instanceof Closure => $rule->where($constraint),
$constraint instanceof WhereConstraint => $rule->where(...$constraint->toArray()),
$constraint instanceof WhereNotConstraint => $rule->whereNot(...$constraint->toArray()),
$constraint instanceof WhereNullConstraint => $rule->whereNull(...$constraint->toArray()),
$constraint instanceof WhereNotNullConstraint => $rule->whereNotNull(...$constraint->toArray()),
$constraint instanceof WhereInConstraint => $rule->whereIn(...$constraint->toArray()),
$constraint instanceof WhereNotInConstraint => $rule->whereNotIn(...$constraint->toArray()),
default => throw new InvalidArgumentException('Each where item must be a DatabaseConstraint or Closure'),
};
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to move this to a trait since we duplicate the code?

Comment on lines 8 to 9
public readonly mixed $column,
public readonly mixed $value = null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know indeed laravel has a mixed type but they provide typehints, let's use those. For value mixed is allright since it probably is really mixed. Another thing I would like to see is support for ExternalReference since we can dynamically replace the value which might be useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion! I've updated the PR to allow the use of ExternalReference. I also added types to the database constraints to the ones that I found made sense.

I took the type suggestions from https://api.laravel.com/docs/11.x/Illuminate/Validation/Rules/DatabaseRule.html

I kept the $value of the WhereConstraint and WhereNotConstraint as mixed, like you said they probably really are mixed.

The type suggestion for whereNot does not include null, but that is supported.

This would otherwise error:

new WhereNotConstraint('deleted_at', null)

Which is not a big deal, since you can use WhereNullConstraint instead, but it makes me think there are other inputs which are not in the type but are supported

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.

2 participants