Mohammad Jawad Barati
Mohammad Jawad Barati
خواندن ۳ دقیقه·۴ سال پیش

بررسی onDelete و onUpdate در Sequelize

قبل از اینکه این پستو بخونی شاید برات بهتر باشه به این پستم یه نگاهی بندازی. یادتم باشه که onUpdate هم مثل onDelete هس. پس فهمیدن onDelete = با فهمیدن onUpdate هس.

B.hasMany(A, { onDelete: 'CASCADE' }); A.belongsTo(B, { onDelete: 'CASCADE', onUpdate: 'CASCADE' })

مقدار پیشفرض onDelete تو belongsTo اینه: 'SET NULL|NO ACTION'. حالا اگه کلید خارجی (کلید اصلی مدل B) تو مدل A اگه بتونه null بگیره null میشه وگرنه no action وارد عمل میشه و مقدار کلید خارجی اصلا پاک نمیشه.

حالا اگه مثل این جا onDelete رو CASCADE بدی وقتی داری یه رکورد از جدول B رو حذف میکنی، همه‌ی اون رکورد هایی تو جدول A حذف میشن که به اون رکورد جدول B وصل بودن. ولی برعکسش اتفاق نمیفته. یعنی اگه A رو حذف کنی رکورد جدول B که کلید اصلیش تو اون رکورد به عنوان کلید خارجی اومده بود حذف نمیشه.

برا مثال وقتی شما جدول پست ها رو می‌سازی و بعدش جدول کامنتا رو. شما انتظار داری اگه یه پستی رو حذف کردی تمام کامنتش هم باهاش حذف بشه ولی برعکسش اتفاق نیفته دیگه. یعنی یه کامنتی رو که برا یه پستی بود اگه حذف کردی نباید پسته حذف بشه.

https://www.aparat.com/v/fLdoh

مقدار پیشفرض onUpdate تو belongsTo اینه: 'CASCADE'. تو این شرایط میاد مقدار کلید خارجی رو به مقدار جدید عوض میکنه. فرض کن که کلید اصلی مدل B ایمیل کاربر بوده. حالا ایمیلشو عوض میکنه. تو این شرایط باید مقدار کلید خارجی رکورد مربوطه تو جدول پروفایل عوض بشه.

Category.belongsToMany(Post, { as: 'Posts', through: 'postCategory', onDelete: 'CASCADE' }); Post.belongsToMany(Category, { as: 'Categories', through: 'postCategory', onDelete: 'CASCADE' });

وقتی شما یه رابطه چند به چند تو sequelize ایجاد می‌کنید و onDelete اش رو CASCADE قرار میدید این اتفاق میفته: وقتی یه پستی رو حذف می‌کنید، تو جدول دسته بندیا هیچ رکوردی حذف نمیشه. بلکه فقط اون رکوردی از توی جدول postCategory حذف میشه که رابط بین رکورد A با رکورد B بود.

این as هم خیلی کاربردی هس. مثلا من برای اینکه بگم یه پست به کدوم دسته بندی وصل بشه به راحتی می‌تونم بگم:

const posts = await Post.findAll({ include: [{ model: Category, as: 'Categories' }] }); const categories = await Category.findAll({ include: [{ model: Post, as: 'Posts' }] }); const category = categories[0], post = posts[0]; post.addCategories(category);

تو تیکه کد بالا بدون اینکه بیام حرکت خاصی بزنم از متد addCategories که خود sequelize بوجودش میاره استفاده می‌کنم و به پست یه دسته بندی اضافه می‌کنم. واقعا من که از کار با sequelize لذت می‌برم. خیلی کار های سخت رو آسون کرده. الیته باید بلد باشی ازش استفاده بکنی.

https://www.aparat.com/v/km6x1

تو یه رابطه یک به یک هم که قضیه خیلی ساده تر میشه. وقتی بگی CASCADE باشه، اون رکورد همراه با اون یکی حذف میشه.

User.hasOne(Profile, { oneDelete: 'CASCADE' }); Profile.belongsTo(User, { oneDelete: 'CASCADE' });

توجه کنید که برای eager loading باید از هر دو طرف برا sequelize بگید که ما یه رابطه ۱:۱ داریم. اگه مثلا خط دومی رو ننویسی و eager loading بکنی به این ارور میخوری:

EagerLoadingError [SequelizeEagerLoadingError]: users is not associated to profiles! at Function._getIncludedAssociation (/home/mjbkhorasani/test-sequelize/node_modules/sequelize/lib/model.js:710:13) at Function._validateIncludedElement (/home/mjbkhorasani/test-sequelize/node_modules/sequelize/lib/model.js:614:53) at /home/mjbkhorasani/test-sequelize/node_modules/sequelize/lib/model.js:509:37 at Array.map (<anonymous>) at Function._validateIncludedElements (/home/mjbkhorasani/test-sequelize/node_modules/sequelize/lib/model.js:504:39) at Function.findAll (/home/mjbkhorasani/test-sequelize/node_modules/sequelize/lib/model.js:1723:12) at processTicksAndRejections (internal/process/task_queues.js:97:5) at async Object.exports.readProfiles (/home/mjbkhorasani/test-sequelize/services.js:13:16) at async exports.getIndex (/home/mjbkhorasani/test-sequelize/controllers.js:6:26)

برای درک بهترتون یه ویدئوی خیلی کوتاه تو آپارات براتون گذاشتم:

https://www.aparat.com/v/8rOBp

هر چیزی برات نامفهوم بود اول برو پست های قبلیمو بخون بعدش اگه بازم مشکلی داشتی باهام درمیون بزار

node.js.developers.kh

nodejssequelizeassociations in sequelizenodejs tutorialnode js
برنانه نویس، مدرس، محقق. عاشق انیمه هستم و دنبال چالش ها جدید.
شاید از این پست‌ها خوشتان بیاید