fogley's avatar

Custom save method for model returning false on unique constraint violation

So, I'm a little tired of constantly combating whether or not I'm currently about to violate a unique constraint in my database. As an experiment I've made the following model function that silently processes the 23000 constraint violation error code and returns false if one such should occur.

    public function saveOrFalse(){
        try{
            return $this->save();
        }catch(QueryException $e){
            if($e->getCode() == 23000){
                return false;
            }
            return $e;
        }
    }

It works precisely as I would expect and could end up lighten my workload a lot.

How would I go about adding this function to the Model class itself so I can avoid adding it to all my classes manually? Is this a bad idea? How bad practice is this? Is the overhead massive compared to checking prior to saving?

Assuming it's out of the question for any sane developer, do you have any alternatives?

0 likes
4 replies
ahmeddabak's avatar

It is not good to let the query fail silently, it is not a good practice, try validating the data in the controller or in a form request class. you can check there for any constraints and you can create you own custom ones. this way you validate your data and when something violate a constraint you will be redirected to the input form with a message that tells you what should be changed.

Laravel Validation

fogley's avatar

@AHMEDDABAK - The thing is, the data created is a randomized string used as an identifier, there's nothing to redirect to. This is only used in internal loops to create an entry with valid data:

while(!$model->saveOrFalse()){
    $model->identifier = str_random(5);
}

This saves me a loop to check the current values in the DB before saving the model.

fogley's avatar

@AHMEDDABAK - uniqid() returns an (at least) 13 character long string which is not viable for me. I need to be able to save guaranteed unique strings of 5 characters in length.

Please or to participate in this conversation.