تریگر چیست و در لاراول چگونه باید ازش استفاده کرد
تریگر (یا رهانا) در sql باعث میشه ما رویه جدولی که میخواهیم نظارت کنیم و اکشنی در قبال رخدادی که روی جدول ما اتفاق میوفته رو مدیریت کنیم مثلا جدولی ساختیم که با x رابطه داره ولی از نوع foreign key تعریف نشده ! من در صورتی که میخوام اطلاعات سمت راست رابطه رو هم حذف کنم مجبورم یا از کد sql استفاده کنم یا از کد php داخل لاراول وقتی ما میخواهیم از php استفاده کنیم باید از model event استفاده کنیم و خودمونو در گیر مسائل دیتابیس نکنیم . ولی لاراول این امکان رو میده من تو migration ها هم تریگر بسازم که چیز جالبیه و در ادامه میگم
خوب برای شروع ساخت تریگر در دیتابیس ما باید با سینتکسش آشنا بشیم
CREATE TRIGGER {trigger name} {BEFORE/AFTER} {DELETE/UPDATE/INSERT} ON {tableName}
FOR EACH ROW
در نمونه کد بالا ما حالتی که قرار اتفاق بیوفته و نظارت کنیم داخل براکت نوشته شده ولی اینجا ما باید با چند مفهوم اصلی اشنا بشیم :
- OLD : همونطور که از اسمش معلومه مقدار گذشته فیلد رو هدف قرار میده زمانی به کار ما میاد که میخواهیم یه ستون رو آپدیت کنیم و یا حذف کنیم و در بعضی مواقع ما میخواهیم بر اساس فیلدی جدولی بسازیم
- NEW : زمانی که ستونی اپدیت میشه ! در حقیقت دو مقدار قدیمی و جدید وجود داره New به مقدار جدید اشاره میکنه
برای مثال ما میخواهیم جدول users رو هدف بگیریم و افرادی که حذف شدن رو مشخصات mobile رو در جدولی لاگ بگیریم به راجتی ما میتوانیم این کار رو انجام بدیم :
CREATE TRIGGER `user_delete` BEFORE DELETE ON `users`
FOR EACH ROW
BEGIN
END
در کد بالا با دو مفهوم جدید اشتا دارید میشید BEGIN , END دقیقا شبیه براکت ها در زبان برنامه نویسی باعث ساخت یک بلاک میشوند
ولی ما باید زمانی ازشون استفاده کنیم که چندین خط کد داشته باشیم. در کد ما حلقه ای ساختیم تا رکورد ها رو تغییر روشون اعمال شد پیشمایش کنه پس کد اصلا ما اینطوری میش ولی باید داخل براکت خودمون این رکورد های حذف شده رو تو جدول دیگه ای بنویسیم برای
CREATE TRIGGER `user_delete` BEFORE DELETE ON `users` FOR EACH ROW
INSERT INTO log (username , mobile , email ) VALUES (OLD.username , OLD.mobile , OLD.email )
پس در کد بالاما وقتی که سطری رو از جدول users پاک میکنیم مشخصات username,email,mobile به جدول لاگ فرستاده میشود و در اونجا ذخیره میشه !
یه مثال از new میخوام بزنم : یه تریگر برای من بساز زمانی که کاربر مقدار username شو تغییر username قبلی , جدیدشو داخل جدول لاگ ذخیره کن ؟
CREATE TRIGGER `user_update` BEFORE UPDATE ON `users` FOR EACH ROW
INSERT INTO log
(user_id , prev_username , current_usernames )
VALUES
( OLD.id , OLD.username , NEW.username );
پس الان ما تونستیم لاگ اطلاعات کاربر رو بگیریم و برای حذف تریگر هم ما میتونیم از کد زیر استفاده کنیم
DROP TRIGGER {trigger name}
ولی قضیه در لاراول فرق میکنه ! ما میتونیم خیلی راحت از model event استفاده کنیم یا یک مایگریت جدید بسازیم !
برای model event داکیومنت پر بار لاراول بهتر توضیح داده ولی من قسمت ساخت مایگریشن رو میگم برای ساخت تریگیر باید دستور زیر رو داخل کنسول بزنید
php artisan make:migration {trigger_name}
و بعد مایگریت کنید تا به دیتابیس اضافه بشه
و بعد فایل مایگریشن رو باز کنید ولی ما درمتد up , down باید چی وارد کنیم ؟!
خوب از اونجایی که لااورل توانایی ساخت تریگر رو به وسیله کلاس blueprint به ما نداده پس ما باید از کلاس DB استفاده کنیم ! پس ما در متد up باید بنویسیم
public function up()
{
DB::unprepared("{SQL CODE}");
}
پس ما کد SQL خودمونو به متد unprepared اضافه میکنیم همین کار رو باید متد down انجام بدیم تا تریگر رو موقع حذف کنیم .