P
P
Pychev Anatoly2021-07-10 15:15:23
Validation
Pychev Anatoly, 2021-07-10 15:15:23

How to properly validate according to technical conditions?

Hello
I ask for help in making a constructive decision.
Itself in Laraverl recently, so I ask you not to kick, but to guide.

Introduction.
There is a project for cutting parts from a sheet (furniture).
Resp. each detail has its own characteristics, which are stored directly in the details table, and related characteristics, which are stored in another table. Therefore, when a user types in a detail, he uses several popups, and when each one is closed, a request to save flies. Each such request has its own (different from others) array of passed parameters and its own handler in the controller.
Then there are technical conditions where restrictions are indicated for certain parameters and sometimes depending on the values ​​of other parameters.
To check the technical conditions, it was decided to use validation methods. Therefore, for each handler, a custom request was created in which all the transferred attributes are added and checked, as well as additional (virtual) ones. For example, the user enters the width and length and it is necessary to check the area limit. Therefore, a new "area" attribute and a validation rule for it are added in the custom request.
And everything works like a song,
YET it was not necessary to do a check on dependent parameters (which are in different popups and, accordingly, in different requests). As a result, I ended up duplicating code in my custom requests.

Idea:
Create your own validation rules, but not to validate values ​​(like min,max, etc.) but to validate an attribute. As a result, I will have each custom rule for each of those conditions

custom rule example

class CuttingMinDimension implements Rule
{
    protected $validator;

    public function __construct( $validator) {
        $this->validator = $validator;
    }

    public function passes($attribute, $value)
    {
        // из конфига возвращается массив [50,100]
        $l_sizes = config( 'cutting.min_sizes' );
        $min = min( $l_sizes );
        $max = max( $l_sizes );

        // Получается что здесь я полностью игнорирую переданное мне значение $value
        // и использую то которое достаю из переданных в  валидатор

        $data = $this->validator->getData();
        $value = $data['cutting_dimension'];

        return $value['min'] >= $min && $value['max'] >= $max;
    }

    public function message()
    {
        return '';
    }
}

And if there are 100-150 technical conditions, I will have 100-150 classes of rules. One for each.
Accordingly, for each of my custom requests, I will be able to use my own unique set of rules, preparing all the necessary virtual attributes accordingly.

An example of a custom request with a virtual attribute
class UpdateDetailsRequest extends FormRequest {

    /**
     * Добавляем виртуальные параметры запроса в массив параметров валидации.
     * @return array
     */
    public function validationData() {
        return array_merge(
            parent::validationData(),
            $this->paramCuttingDetailDimension(),
        );
    }

    /**
     * Параметр габоритные размеры детали.
     *
     * @return array
     */
    protected function paramCuttingDetailDimension() {
        // Здесь width и length это атрибуты которые задает пользователь

        $min_d = min( $this->width, $this->length );
        $max_d = max( $this->width, $this->length );

        // это и есть наш виртуальныей параметр и его значения.
        return [ 'cutting_dimension' => [ 'min' => $min_d, 'max' => $max_d ] ];
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules() {
        return array_merge(
            [],
            $this->ruleCuttingDimension(),
        );
    }

    /**
     * Проверка на мин габоритные размеры по порезке.
     *
     * @return array
     */
    protected function ruleCuttingDimension() {
        return [
            'cutting_dimension' => [
                'required',
                'cutting_min_dimension', // тут просто указываем наше кастомное правило.
            ],
        ];
    }

}


The connection of the rules goes to app/Providers/AppServiceProvider.php according to the documentation
public function boot()
    {
        Validator::extend('cutting_min_dimension', function ($attribute, $value, $parameters, $validator) {
            return (new CuttingMinDimension($validator))->passes($attribute, $value);
        });
    }


Now the question:
I understand that I violate the general concept of using the Rule class a bit by uniqueizing it for an attribute.
Perhaps there are some underwater kami of such use of Rule, which I do not see?
Whether it will turn out that in the future I can pay for such decision, for example speed of processing of requests?

Maybe someone has already encountered such problems and has an idea for a more concise solution.
Many thanks for the replies.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
inFureal, 2021-08-19
@inFureal

I don't see any problem. There are rules like required_if , required_unless that look at values ​​from other keys

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question