Skip to content

Conversation

@cosmastech
Copy link
Contributor

@cosmastech cosmastech commented Dec 17, 2024

This is to make it easier to handle invalid route keys without having to override HasUniqueStringIds@resolveRouteBindingQuery() method (which would be a lot of duplication and create maintenance overhead).

This consolidates code a little bit into a common method handleInvalidUniqueId which should throw an exception. There is no breaking change here, as we're still throwing the same ModelNotFoundException. For a team that wishes to customize their return type (such as indicating this is a 422 response, not a 404), they can easily do that as follows:

// custom exception
class InvalidTwrnException extends \RuntimeException implements Responsable
{
    public $key;

    public function setTwrn($key)
    {
        $this->key = $key;

        return $this;
    }

    public function toResponse($request)
    {
        return response()->json(['message' => 'invalid twrn', 'twrn' => $this->key], 422);
    }
}

// the trait
trait HasTwrnsTrait
{
    use HasUniqueStringIds;

    public function newUniqueId()
    {
        return (string) Twrn::new();
    }
  
    protected function isValidUniqueId($value): bool
    {
        return Twrn::isValid($value);
    }

    protected function handleInvalidUniqueId($value, $field): never
    {
        throw (new InvalidTwrnException)->setTwrn($value);
    }
}

*/
protected function handleInvalidUniqueId($value, $field)
{
throw (new ModelNotFoundException)->setModel(get_class($this), $value);
Copy link
Contributor

@shaedrich shaedrich Dec 17, 2024

Choose a reason for hiding this comment

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

You could even put the exception name as static property on the model so ModelNotFoundException is taken as a default but can be overwritten without overwriting handleInvalidUniqueId() when one just wants to change the class name

Suggested change
throw (new ModelNotFoundException)->setModel(get_class($this), $value);
throw (new $notFoundException)->setModel(get_class($this), $value);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good idea, but I think it would require the class to implement setModel() which isn't enforced by an interface.

Copy link
Contributor

@shaedrich shaedrich Dec 17, 2024

Choose a reason for hiding this comment

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

Good point 👍🏻 Maybe this can be implemented via an interface then 🤔

 trait HasUniqueStringIds
 {
+    private ModelException $notFoundException = ModelNotFoundException
interface ModelException
{
    /**
     * Set the affected Eloquent model and instance ids.
     *
     * @param  class-string<TModel>  $model
     * @param  array<int, int|string>|int|string  $ids
     * @return $this
     */
    public function setModel($model, $ids = []);
}

@taylorotwell taylorotwell merged commit b6f5f02 into laravel:11.x Dec 17, 2024
38 checks passed
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.

3 participants