php - 为什么基于注册类型容量的验证不起作用?
问题描述
我有一个选择菜单供用户选择会议的每种注册类型的数量:
@foreach($registration_types as $rtype)
<li>
<div>
<span>{{$rtype->name}}</span>
</div>
@if(min($rtype->max_participants, ($rtype->capacity - $rtype->participants->count())) == 0)
Out of capacity
@else
<select
id="rtype_{{ $rtype->id }}"
data-price="{{ $rtype->price }}"
name="rtypes[{{ $rtype->name }}]">
<option value="0">0</option>
@for ($i = $rtype->min_participants; $i <= min($rtype->max_participants, ($rtype->capacity - $rtype->participants->count())); $i++)
<option value="{{ $i }}">{{ $i }}</option>
@endfor
</select>
@endif
<span>X {{$rtype->presentPrice()}}
€</span>
</li>
@endforeach
我想验证用户在选择菜单中引入的数量。
如果出现以下情况,我已经有一个RegistrationTypeQuantity
返回 false 的自定义规则:
- 用户没有为无注册类型选择无数量,点击“下一步”
- 用户没有在注册类型的 min_participants 和 max_participants 列之间选择一个值,然后单击“下一步”
否则,它会通过。
RegistrationQuantity 自定义规则:
public function passes($attribute, $value)
{
$count = array_sum($value);
if($count == 0){
return false;
}
foreach($value as $key=>$v) {
$rtype = RegistrationType::where('name',$key)->first();
if ( !$rtype ){
return false;
}
if ( $v != 0 && ($v < $rtype->min_participants || $v > $rtype->max_participants) ){
return false;
}
}
return true;
}
所以这工作正常。
怀疑:
但也需要验证用户引入的数量考虑注册类型的容量列。每个注册类型都有一个容量。
因此,例如,如果注册类型“general”的容量为 10,并且已经有 10 名参与者在注册类型“general”中注册。如果用户为注册类型“general”引入数量“10”并单击 Next,它应该会导致验证错误。
另外,如果注册类型“general”的数据库容量为 10,min_participants 为 1,最大参与者为 3,并且注册类型为“general”的参与者有 8 名,则选择菜单中仅显示 1 和 2。因此,如果例如,用户输入数量的值“3”并单击“下一步”它应该显示验证错误,因为用户应该只被允许选择数量 1 或 2,因为 8 个参与者 + 3 = 11 并且总容量是10. 所以验证应该失败。
但是将以下代码添加到规则的passes()
方法中RegistrationTypeQuantity
无法实现此验证:
if ($v <= min($rtype->max_participants)
&& ($rtype->capacity - $rtype->participants->count())){
return false;
}
考虑到注册类型的容量,您知道如何正确验证引入的数量吗?
解决方案
试试这个..
public function passes($attribute, $value)
{
if(array_sum($value) < 1){
return false;
}
foreach($value as $key=>$v) {
if ( $v != 0) {
$rtype = RegistrationType::where('name',$key)->withCount('participants')->first();
if ( !$rtype ){
return false;
}
if ($v < $rtype->min_participants || $v > $rtype->max_participants || (($rtype->capacity - $rtype->participants_count) < $v) ){
return false;
}
}
}
return true;
}
仅当所选数量为 时,此验证规则才会通过:
介于min_participants
和max_participants
小于(容量 - 当前参与者)
选修的:
您的验证规则将进行n
查询次数,您可以将其减少到一个。其中n
是用户选择的注册类型的数量。
看法
@foreach($registration_types as $rtype)
<li>
<div>
<span>{{$rtype->name}}</span>
</div>
@if(min($rtype->max_participants, ($rtype->capacity - $rtype->participants->count())) == 0)
Out of capacity
@else
<select id="rtype_{{ $rtype->id }}" data-price="{{ $rtype->price }}" name="rtypes[{{ $rtype->id }}]">
<option value="0">0</option>
@for ($i = $rtype->min_participants; $i <= min($rtype->max_participants, ($rtype->capacity - $rtype->participants->count())); $i++)
<option value="{{ $i }}">{{ $i }}</option>
@endfor
</select>
@endif
<span>X {{$rtype->presentPrice()}} €</span>
</li>
@endforeach
请注意,name
数量选择的属性已更改。[索引从$rtype->name
变为$rtype->id
。
验证规则
public function passes($attribute, $value)
{
if(array_sum($value) < 1){
return false;
}
$rTypes = RegistrationType::withCount('participants')->whereIn('id',array_keys($value))->get();
foreach($rTypes as $rType) {
if ( $value[$rType->id] != 0) {
if ($value[$rType->id] < $rtype->min_participants || $value[$rType->id] > $rtype->max_participants || (($rtype->capacity - $rtype->participants_count) < $value[$rType->id]) ){
return false;
}
}
}
return true;
}
请注意,whereIn
用于在单个查询中访问所有必需的记录。使用数量数组上的方法id
访问的s 数组。array_keys
如果我没有测试过,请告诉我是否遇到任何问题。
推荐阅读
- c# - Xamarin 表单应用程序在 SerializeObject 处崩溃未产生错误
- javascript - React:将具有给定参数的函数传递给孩子
- java - 按钮单击不切换活动
- kubernetes - Kubernetes - 何时使用 HorizontalPodAutoscaler 资源类型?
- discord.py - 如何在本地计算机中使用我自己的图像进行 discord.py 机器人嵌入?
- bash - 将命令的输出存储在变量中
- r - 从一副牌中抽牌直到你得到一对
- sql - 如何打印常量的数据类型
- python - Marshmallow JSONAPI:模式序列化和反序列化不是对称的?
- python - 根据不同列表的值复制列表中的项目