首页 > 解决方案 > 如何使验证在日期和某些数字列上唯一,但日期只需要年月

问题描述

我尝试在 LARAVEL 上制定独特的规则,即 YYYY-MM 和 NUMBER_COLUMN 是否相同 = 返回错误/警告。但我只能使 YYYY-MM-DD 和 NUMBER_COLUMN 相同 = 返回错误。

所以,当我尝试输入相同的 number_column 但不同的一天时,它会输入到表中,我希望 number_column 在一个月内不能相同

我的代码:

$form->number('deed_number', 'Nomor Akta')->placeholder('Nomor Akta')
    ->creationRules(['required', "unique_month_date"])
    ->updateRules(['required', "unique_month_date"]);
$form->date('date', 'Tanggal Akta')->placeholder('Tgl Akta')->rules('required');

我想要的表:

NUMBER_COLUMN ; DATE_COLUMN

1 ; 2019-10-19 [Allowed]

2 ; 2019-10-19 [Allowed]

3 ; 2019-10-19 [Allowed]

3 ; 2019-10-20 [NotAllowed] <<< But it acceptable into database for current rule

deed_notary_numbers:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateDeedNotaryNumbersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('deed_notary_numbers', function (Blueprint $table) {
            $table->increments('id');
            $table->bigInteger('number')->unique();
            $table->integer('deed_number');
            $table->string('date');
            $table->string('title');
            $table->tinyInteger('creditor_id');
            $table->tinyInteger('creditor_manager_id');
            $table->tinyInteger('costumer_id');
            $table->tinyInteger('user_id')->nullable();
            $table->longText('notes')->nullable();
            $table->timestamps();
            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('deed_notary_numbers');
    }
}

标签: phplaravel

解决方案


我的理解是,您不希望允许表单提交当前月份的数字和日期已经存在的数据

试图重现这一点,我想出了这个解决方案

<?php

namespace App\Http\Controllers;

use App\Foo;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class FooController extends Controller
{
    public function store(Request $request)
    {
        $date = Carbon::createFromDate($request->date);
        $month = $date->format('Y-m'); // Keep year attached
        $days = $date->daysInMonth;
        $request->validate([
            'date' => 'required|date',
            'number' => [
                'required',
                'integer',
                Rule::unique('foos')->where(function ($query) use ($request, $month, $days) {
                    return $query
                        ->whereBetween('date', ["$month-01", "{$month}-{$days}"])
                        ->whereNumber($request->number);
                }),
            ],
        ]);
        $foo = new Foo();
        $foo->date = $request->date;
        $foo->number = $request->number;
        $foo->save();
        return $foo;
    }
}

给定这样的表格

<form action="/" method="post">
    @csrf
    <input type="date" name="date" value="2019-10-19"><br>
    <input type="number" name="number" value="3"><br>
    <button type="submit">Submit</button>
</form>
@if ($errors->any())
<div class="alert alert-danger">
    <ul>
        @foreach ($errors->all() as $error)
        <li>{{ $error }}</li>
        @endforeach
    </ul>
</div>
@endif

还有这样的路线

Route::post('/', 'FooController@store');

像这样的表迁移

Schema::create('foos', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->date('date');
    $table->integer('number');
    $table->unique(['date', 'number']);
    $table->timestamps();
});

结果:

第一次发布 2019 年 10 月 19 日和 3 有效
第二次发布相同的无效
发布 10-20-2019 和 3 无效(3 已经存在于 10 月)
使用不同的数字发布有效 发布 2019 年 11 月 19 日
和3 有效

希望这可以帮助


推荐阅读