Здравствуйте
Прошу помощи в принятии конструктивного решения.
Сам в Лараверл недавно, поэтому прошу не пинать, а направлять.
Введение.
Есть проект по порезке деталей с листа (мебельный).
Соотв. каждая деталь имеет собств характеристики, которые храняться напрямую в таблице details и связанные характеристики, которые хранятся в другой таблице. Поэтому когда пользователь набирает деталь он пользуется несколькими попап-ами и при закрывании каждого летит запрос на сохранение. Для каждого такого запроса есть свой (отличный от других) массив передаваемых параметров и свой обработчик в контроллере.
Далее есть техусловия где указываются ограничения для тех или иных параметров и иногда в зависимости от значений других параметров.
Для проверки техусловий было решено использовать методы валидации. Поэтому для каждого обработчика был создан кастомный реквест в котором добавляются и проверяются все переданные атрибуты а также дополнительные (виртуальные). Например пользователь вводит ширину и длину а надо проверить ограничение по площади. Поэтому в кастомном реквесте добавляется новый атрибут "area" и правило проверки для него.
И все работает как песня,
ПОКА не потребовалось делать проверку по зависимым параметрам(которые находятся в разных попап-ах и соотв. в разных реквестах). В результате я пришел к дублированию кода в своих кастомных реквестах.
Идея:
Создать собственные правила проверки, но не для проверки значений (как min,max и т.д.) а для проверки атрибута. В результате у меня будет по каждому кастомному правилу на каждое тех условие
пример кастомного правила
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 '';
}
}
И если будет 100-150 техусловий у меня будет 100-150 классов правил. Для каждого по одному.
Соответственно для каждого моего кастомного реквеста я смогу использовать свой уникальный набор правил, подготовив соотв все необходимые виртуальные атрибуты.
Пример кастомного реквеста с виртуальным атрибутом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', // тут просто указываем наше кастомное правило.
],
];
}
}
Подключение правил просходит в app/Providers/AppServiceProvider.php согласно документации
public function boot()
{
Validator::extend('cutting_min_dimension', function ($attribute, $value, $parameters, $validator) {
return (new CuttingMinDimension($validator))->passes($attribute, $value);
});
}
Теперь вопрос:
Я понимаю что немного нарушаю общую концепцию использования класса Rule уникализируя его для атрибута.
Возможно есть какие то подводные ками такого использования Rule, которых я не вижу?
Не получится ли что в будущем я могу поплатится за такое решение, например скоростью обработки запросов?
Может кто то уже сталкивался с такими задачами и есть идея более лаконичного решения.
Большое спасибо з ответы.