در جلسه قبل با موفقیت اعتبارسنجی را برای فرم خود پیاده سازی کردیم تا شامل فیلد username نیز بشود اما هنوز کارمان تمام نشده است. اگر یادتان باشد ما پایگاه داده خود را با استفاده از migration ها ساخته بودیم. برای مرور به پوشه database و سپس migrations می رویم و فایل create users table را باز می کنیم (معمولا نامی شبیه به 2014_10_12_000000_create_users_table.php دارد). من در جلسات قبل توضیح دادم که هر فایل migration یک کلاس است که دو متد up و down دارد:
به محتوای متد up در فایل Create users table توجه کنید:
public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); }
دستور schema::create یک جدول جدید می سازد. واژه schema به معنی «طرح» است و منظور آن مشخص کردن طرح جدول های پایگاه داده است. من صحبت های جلسه 6 را تکرار نمی کنم بلکه می خواهیم این migration را ویرایش کنم. هر کدام از ساختارهای ()X<-table$ نشان دهنده یک ستون در جدول users هستند:
بنابراین باید یک ستون جدید برای username اضافه کنیم:
public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->string('username')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); }
من username را در قالب یک رشته اضافه کرده ام که باید یکتا (unique) باشد. فعلا این را در ذهنتان داشته باشید که ما فایل migration را ویرایش کردیم اما پایگاه داده ما قبلا ساخته شده است و تغییرات این فایل را باید روی پایگاه داده نیز پیاده کنیم.
حالا به فایل RegisterController.php برگشته و به متدهای validator و create نگاهی بیندازید:
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'], ]); } protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), ]); }
اگر متد validator بدون خطا اجرا شود و تمام داده های ارسالی معتبر باشند، روند اجرای کدها ادامه پیدا می کند اما اگر خطایی در آن ها پیدا کنیم (مثلا ایمیل تکراری باشد) آنگاه اجرای کدها متوقف شده و خطایی به کاربر برمی گردد. بیایید فرض کنیم که validator اجرا شود و هیچ خطایی نداشته باشیم؛ در این حالت متد create اجرا خواهد شد. این متد مسئول ساخت یک کاربر در پایگاه داده ما است اما در اینجا username را نداریم و فیلد username نیز نمی تواند خالی باشد بنابراین آن را اضافه می کنیم:
protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'username' => $data['username'], 'password' => Hash::make($data['password']), ]); }
حالا کدها را ذخیره کرده و به مرورگر بروید و یک کاربر جدید را ثبت نام کنید (با مقادیر دلخواه):
به محض کلیک روی دکمه register با خطای زیر روبرو می شوید:
Illuminate\Database\QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'username' in 'where clause' (SQL: select count(*) as aggregate from `users` where `username` = newUser)
این خطا می گوید که ستونی به نام username در پایگاه داده شما وجود ندارد! برای تست این موضوع ترمینال جدیدی را در مسیر پروژه خود باز کرده و دستور زیر را در آن اجرا کنید:
php artisan tinker
دستور tinker به شما اجازه می دهد که به صورت مستقیم با برنامه خود در ترمینال تعامل داشته باشید. پس از اجرای این دستور وارد محیط خاصی می شوید که با علامت <<< مشخص شده است. حالا در این محیط دستور زیر را اجرا کنید:
User::all();
با اجرای این دستور تمام کاربران در پایگاه داده برای ما برگردانده می شوند. نتیجه اجرای دستور بالا برای من بدین شکل است:
[!] Aliasing 'User' to 'App\User' for this Tinker session. => Illuminate\Database\Eloquent\Collection {#3858 all: [ App\User {#3791 id: 1, name: "Amir", email: "myEmail@email.com", email_verified_at: null, created_at: "2020-06-21 06:18:35", updated_at: "2020-06-21 06:18:35", }, ], }
طبیعتا فیلد password به صورت خودکار مخفی شده و نمایش داده نمی شود اما بقیه فیلدها حضور دارند. در اینجا می بینیم که کاربر new user وجود ندارد و خبری از ستون username هم نیست. آیا دلیل آن را می دانید؟ بله! ما فایل migration را تغییر دادیم اما هنوز این تغییرات را از فایل روی پایگاه داده اعمال نکرده ایم. برای انجام این کار می گوییم:
php artisan migrate:fresh
با اضافه کردن قسمت Fresh گفته ایم که همه چیز در پایگاه داده ما را حذف کن و سپس migrations ها را دوباره انجام بده. به نظر شما با اجرای این دستور مشکل حل می شود؟
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.