در مقاله قبل آرشیوی از دستورات اولیه و مهم لاراول رو نوشتم تا هر موقع نیاز شد بازبینی داشته باشم. در آرشیو دوم سعی میکنم برخی مفاهیم جدید که یاد میگیرم را به اشتراک بذارم.
۱ – تفاوت بین PUT و PATCH در فرمهای لاراول :
وقتی یک فرم با متد post ارسال میشود یک resource در سرور ایجاد میشود. اگر کاربر درخواست مشابهی رو دوبار وارد کند برای درخواست دوم resource جدید ایجاد میشود. در واقع ارسال فرم با متد post همان INSERT یک رکورد در دیتابیس است.
http post method is like a INSERT query in SQL which always creates a new record in database.
برای مثال ثبت یک مطلب، کاربر و سفارش در وبسایت همگی با متد post انجام میشود.
put و patch درخواست های http هستند که هر دوی آنها اطلاعات را بروزرسانی میکنند.
متد PUT :
ارسال فرم با متد put به این صورت عمل میکند ابتدا با استفاده از شناسه ای که دریافت میکند ابتدا بررسی میکند تا از موجودیت رکورد مورد نظر در دیتابیس مطمئن شود اگر رکورد وجود داشت همان رکورد را بروزرسانی میکند و درواقع اطلاعات جدید ارسال شده کاملا جایگزین میشود ولی اگر بعد از بررسی دیتایی وجود نداشت در واقع آن یک resource جدید در سرور ایجاد میکند و اطلاعات را در دیتابیس ثبت میکند.
http put method is like a MERGE query in SQL which inserts or updates a record depending upon whether the given record exists.
در متد PUT اگر چند درخواست مشابه ارسال شود با توجه به شناسه ای که ارسال میشود همان resource که پیدا شده است بروز رسانی میشود و resource جدیدی در سرور ایجاد نمیشود. در واقع در این متد شناسه resource توسط کاربر ارسال میشود.
برای مثال وقتی سفارش مشتری، مطلب وبلاگ و یا کاربری که وجود دارد را بروزرسانی میکنیم.
متد PATCH :
از متد patch برای بروزرسانی بخشی از یک resource (داده، اطلاعات) استفاده میکنیم. در واقع در این متد همه اطلاعات ارسال نمیشود که کاملا جایگزین رکورد فعلی دیتابیس شود.
http patch method is like a UPDATE query in SQL which sets or updates selected columns only and not the whole row.
برای مثال وقتی وضعیت یک سفارش مشتری را تغییر میدهیم از این متد استفاده میکنیم. ( PATCH request requires less bandwidth. )
۲ – ست کردن Session بعد از ریدایرکت :
وقتی رکوردی در دیتابیس اضافه میشود و یا تغییری اعمال میشود، ما یک session به صفحه ارسال میکنیم تا تغییر مورد نظر را تایید و یا رد کند. به صورت زیر این کار را انجام میدهیم:
return redirect()->back()->with('success', ['your message,here']);
برای نمایش پیام ست شده در blade به صورت زیر عمل میکنیم :
@if (\Session::has('success')) <div class="alert alert-success"> <ul> <li>{!! \Session::get('success') !!}</li> </ul> </div> @endif
۳ – نکته ای در مورد migration :
در پروژه ای که انجام میدادم نیاز بود یکی از فیلدهای دیتابیس را از حالت UNIQUE خارج کنم. برای اینکار یک مایگریشن ایجاد کردم و به صورت زیر اجرا کردم.
public function up() { Schema::table('users', function(Blueprint $table) { $table->dropUnique('email'); }); }
پس از اجرای مایگریشن، متوجه شدم که به درستی اجرا نمیشه و عمل نمیکنه. نکته ای که وجود دارد این است که :
To drop an index you must specify the index’s name. Laravel assigns a reasonable name to the indexes by default. Simply concatenate the table name, the names of the column in the index, and the index type.
وقتی فیلد را UNIQUE کردم ایندکس شد و برای اینکه از حالت UNIQUE خارجش کنم باید نام ایندکس آن را داخل مایگریشن قرار دهم به صورت زیر :
$table->dropUnique('users_email_unique');
در قسمت دیگری که مایگریشن را ایجاد میکردم، باید فیلد دیتابیسی که کلید خارجی بود را از حالت کلید بودن بر میداشتم برای اینکار باید dropForeign با سبکی نوشته میشد که مطابق قاعده مایگریشن ها باشد.
برای مثال وقتی در جدول boxes فیلدی به نام type_id داریم و کلید خارجی به جدول دیگری است
$table->integer('type_id')->unsigned(); $table->foreign('type_id')->references('id')->on('table');
باید برای dropForeign آن به صورت زیر اقدام میکردم :
<table_name>_<column_name>_foreign
یعنی به صورت زیر :
$table->dropForeign('boxes_type_id_foreign');
۴ – دریافت اولین و آخرین مقدار Foreach در قالب Blade Laravel :
از نسخه لاراول 5.3+ متغیری به نام $loop داخل حلقه ها در دسترس است که میتوانیم کارهای زیر را انجام دهیم :
شمارنده در هر اجرا : در لیست هایی که چاپ میکنیم میتوانیم شمارنده ای را با استفاده از این متغیر چاپ کنیم :
$loop->iteration
دریافت اولین و آخرین مقدار یک آرایه :
@foreach ($menu as $item) <div @if ($loop->first) class="hidden" @endif> <h2>{{ $item->title }}</h2> </div> @endforeach
@foreach ($menu as $item) <div @if ($loop->last) class="hidden" @endif> <h2>{{ $item->title }}</h2> </div> @endforeach
۵ – فیلدهای دیتابیس از نوع JSON و نحوه Eloquent
وقتی دادههایی که در دیتابیس ذخیره میکنیم از نوع JSON باشند فقط یک مقدار را ندارد که به صورت روال قبل داده را دریافت کنیم و از آن در eloquent استفاده کنیم. مثلا داده های json زیر داخل یکی از فیلدهای دیتابیس به نام meta ذخیره شده است :
{ "id": 1, "name": "Alphonse", "meta": { "wants_newsletter": true, "favorite_color": "red" } }
برای اینکه چک کنیم در صورتیکه یکی از ویژگیهای فیلد meta مطابق چیزی است که ما میخواهیم یا خیر به صورت زیر اقدام میکنیم، مثلا میخواهیم در صورتیکه مقدار favoraite_color اگر red بود داده را بگیریم :
$redLovers = DB::table('users') ->where('meta->favorite_color', 'red') ->get();
برای بروزرسانی هم به صورت زیر میتوانیم بنویسیم :
DB::table('users') ->where('id', 1) ->update(['meta->wants_newsletter' => false]);
نکته مهم : MariaDB در حال حاضر از فیلدهای دیتابیس با نوع JSON پشتیبانی نمیکند ولی PostgreSQL و MySQL 5.7+ از این نوع فیلد پشتیبانی میکنند.
۶ – والیدیشن فیلد ایمیل ( یونیک بودن ایمیل )
در فرمهایی که ایجاد میکنیم، برای مثال وقتی که میخواهیم پروفایل کاربر را ادیت کنیم و در جدول کاربران فیلد ایمیل یا هر فیلد دیگری یونیک است در رکوستی که برای والیدیت ( Validation ) فیلدهای ارسالی مینویسیم به صورت زیر اقدام میکنیم :
$rules = [
'email' => 'nullable|email|unique:users,email,' . $this->user,
]
فیلد ایمیل را nullable کردیم و آن را اختیاری قرار دادیم از طرفی میخواهیم این فیلد برای هر کاربر یونیک باشد پس آن را برای جدول users یونیک می کنیم.
وقتی ایمیل کاربر تغییر میکند، یونیک بودن را با سایر فیلدهای دیتابیس چک کند و این رکورد از دیتابیس را با بقیه مقایسه کند. ( در صورتیکه رکورد کاربر فعلی که ادیت میشود را مشخص نکنیم ( $this->user ) خطای تکراری بودن ایمیل باعث میشود نتوانیم کاربری را ویرایش کنیم. )