تکمیل و تصحیح اعتبارسنجی در فرم ثبت‌نام

Completing and Correcting the Validation in the Registration Form

25 بهمن 1399
Laravel 7.0: تکمیل و تصحیح اعتبار سنجی در فرم ثبت نام (قسمت 12)

در جلسه قبل فیلد username را با موفقیت به فرم ثبت نام (register) اضافه کردیم اما به شما گفتم که فرم ما مشکل بزرگی دارد. آیا توانستید که خودتان حدس بزنید این مشکل چیست؟ در حال حاضر فرم ما از اعتبارسنجی پیش فرض در HTML5 نیز استفاده می کند:

<div class="form-group row">
    <label for="username" class="col-md-4 col-form-label text-md-right">Username</label>

    <div class="col-md-6">
        <input id="username" type="username"
            class="form-control @error('username') is-invalid @enderror" name="username"
            value="{{ old('username') }}" required autocomplete="username">

        @error('username')
        <span class="invalid-feedback" role="alert">
            <strong>{{ $message }}</strong>
        </span>
        @enderror
    </div>
</div>

اگر به فیلد نگاه کنید required را می بینید که در مرورگر های امروزی کاربر را مجبور می کند تا مقداری را در فیلد وارد کند. این کار بسیار خوبی است و همیشه باید با جاوا اسکریپت یا HTML (به طور کل در frontend) اعتبارسنجی اولیه را انجام بدهید تا بیهوده بار کاری سرور را با درخواست های متعدد اعتبارسنجی اضافه نکنید. البته از طرفی به هیچ عنوان نباید اعتبارسنجی سمت سرور را حذف کنید چرا که اعتبارسنجی های جاوا اسکریپتی و HTML می توانند به راحتی توسط کاربر غیرفعال شوند.

مسئله اینجاست که ما در حال یادگیری لاراول هستیم بنابراین باید تمام این دستورات required را از تک تک و همه فیلدهای خودمان (فایل register.blade.php) حذف کنیم تا فقط با سیستم اعتبارسنجی لاراول سر و کار داشته باشیم. یک نمونه:

<input id="username" type="username"
    class="form-control @error('username') is-invalid @enderror" name="username"
    value="{{ old('username') }}" autocomplete="username">

پس از حذف required از تمام فیلدها، به مرورگر بروید (صفحه http://127.0.0.1:8000/register) و بدون اینکه چیزی در فرم بنویسید گزینه register را بزنید:

اعتبارسنجی در فرم های لاراول باعث قرمز شدن فیلد ها می شود.
اعتبارسنجی در فرم های لاراول باعث قرمز شدن فیلدها می شود.

همانطور که می بینید دستور error@ در کلاس input کار کرده است و کلاس is-invalid را به فیلدهای خالی اضافه کرده است که باعث قرمز شدن آن ها شده است اما فیلد username که ما تعریف کرده بودیم اصلا قرمز نشده است! آیا دلیل آن را می دانید؟

اگر یادتان باشد در جلسات اولیه این دوره به شما گفته بودیم که لاراول بر اساس معماری MVC کار می کند که یعنی view و model و controller از هم جدا هستند. view ما همین فرمی است که می بینیم اما view ها هیچ وقت نباید منطق PHP یا Laravel (به طور کل منطق عملیاتی و محاسباتی) را در خود داشته باشند، این مسئله وظیفه controller ها است. بنابراین این فرم برای ثبت شدن و عملیات هایی مانند اعتبارسنجی باید به یک کنترلر ارسال شود، درست است؟ حالا این کنترلر کجاست؟

در پوشه اصلی پروژه، پوشه ای به نام app را داریم که درون خود پوشه ای به نام Http را دارد. درون این پوشه، پوشه دیگری به نام Controllers وجود دارد که حاوی تمام کنترلر های برنامه ما است. در controllers پوشه ای به نام Auth داریم که مخصوص نگهداری کنترلر های احراز هویت (ثبت نام و ورود) است. وارد این پوشه شده و فایل RegisterController.php را باز کنید. این فایل قسمت های متعددی دارد اما ما فعلا فقط با این قسمت کار داریم:

protected function validator(array $data)
{
    return Validator::make($data, [
        'name' => ['required', 'string', 'max:255'],
        'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
        'password' => ['required', 'string', 'min:8', 'confirmed'],
    ]);
}

متد validator در این کلاس یک Validator را برمی گرداند بنابراین این متد همان متدی است که ما دنبالش هستیم. فکر نمی کنم این متد نیاز به توضیحات اضافه داشته باشد چرا که همه چیز واضح است. مثلا required یعنی این فیلد اجباری است و نمی تواند خالی باشد، String یعنی مقدار وارد شده باید رشته باشد و max:255 یعنی حداکثر تعداد کاراکتر های مجاز برای آن 255 کاراکتر است. unique:users نیز نوع خاصی از قوانین لاراول است که ایمیل کاربر را در پایگاه داده بررسی می کند تا چنین ایمیلی قبلا ثبت نشده باشد (کسی با یک ایمیل چند حساب نسازد) که بعدا در موردش بیشتر صحبت می کنیم. فعلا بدانید که قسمت اول یا unique یعنی «یکتا بودن» و قسمت دوم یا users نام جدول ما در پایگاه داده است بنابراین این فیلد (Email) باید در جدول users بررسی شده و در آن وجود نداشته باشد. شما می توانید با مراجعه به documentation رسمی Laravel با تک تک این قوانین اعتبارسنجی آشنا شوید:

https://laravel.com/docs/7.x/validation#available-validation-rules

من یک فیلد جدید به این متد validator اضافه می کنم:

protected function validator(array $data)
{
    return Validator::make($data, [
        'name' => ['required', 'string', 'max:255'],
        'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
        'username' => ['required', 'string', 'max:255', 'unique:users'],
        'password' => ['required', 'string', 'min:8', 'confirmed'],
    ]);
}

همانطور که می بینید username را نیز به آن داده ایم و همان قوانین ایمیل را برایش کپی کرده ام (به جز email چرا که لازم نیست username بر اساس ساختار ایمیل باشد). من مقدار unique:users را باقی گذاشته ام. با این کار لاراول key این آرایه را برداشته (یعنی همان رشته username) و به دنبال ستونی با همین نام در جدول users می گردد و اگر چنین مقداری وجود داشته باشد خطا برمی گرداند.

زمانی که فرم را به صورت خالی ثبت کردیم، پیامی مثل The email field is required را برای فیلدهای اجباری دیدیم اما اگر ایمیل خودم را در اینجا ثبت کنم چطور؟ من در جلسات قبل با ایمیل myEmail@email.com ثبت نام کرده بودم بنابراین اگر دوباره با همان ایمیل فرم را پر کنم خطای زیر را می گیرم:

The email has already been taken.

که یعنی این ایمیل قبلا ثبت شده است و همچنین username نیز قرمز می شود:

خطای The email has already been taken برای فیلد یوزرنیم نمایش داده می شود که یعنی این فیلد اجباری است.
خطای The email has already been taken برای فیلد یوزرنیم نمایش داده می شود که یعنی این فیلد اجباری است.

بنابراین تا اینجا سیستم به درستی کار می کند اما این فقط قسمت اعتبارسنجی است! با اضافه کردن یک فیلد جدید به یک فرم، باید یک ستون جدید به همین نام در پایگاه داده داشته باشیم وگرنه تعداد فیلدهای فرم از تعداد ستون های پایگاه داده بیشتر می شوند و MySQL خطا می دهد! در جلسه بعد روی این موضوع کار خواهیم کرد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری ساخت اینستاگرام با Laravel 7 توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.