برا ساختن یه pagination تو نود.جیاس باس چند تا مقدمه بهتون بگم:
یادت باشه که توی Sequelize وقتی رابطه داری، برای Update کردن CASCADE میکنه. برای delete هم SET NULL میکنه، ولی اگه رابطه چند به چند باشه CASCADE میکنه. پس اگه چیز دیگه ای مد نظرت هست باید به صورت صریح به Sequelize بگی.
تو sequelize ما از روابط یک به یک، یک به چند و چند به چند پشتبانی میکنیم. حالا برا ساختن این association چهار تا متد داریم:
این متدا تقریبا به یه شکل استفاده میشن و یه آرگومان دومی هم برا تنظیمات بیشتر دارن. حواست به نحوهی تعریف association باشه. الان تو این مثال A مدل source هس و B مدل target هس. (مثالا رو از داک sequelize برداشتم)
A.hasOne(B, { /* options */ }); A.belongsTo(B, { /* options */ }); A.hasMany(B, { /* options */ }); A.belongsToMany(B, { through: 'C', /* options */ });
خط اول مثال بالا داره میگه یه رابطه یک به یک داریم و کلید اصلی مدل source به صورت خودکار به عنوان کلید خارجی تو مدل target تعریف میشه.
خط دوم داره میگه یه رابطه یک به یک داریم و کلید اصلی مدل target به صورت خودکار به عنوان کلید خارجی تو مدل source تعریف میشه (دقیقا برعکس خط یک).
خط سوم داره میگه یه رابطه یک به چند داریم که کلید اصلی مدل source به صورت خودکار به عنوان کلید خارجی تو مدل target تعریف میشه.
خط چهارم داره میگه یه رابطه چند به چند داریم. برا ایجاد این رابطه sequelize خودش یه جدول جدید میتعریفه (اگه بهش تو رشته مقدار بدید، دقیقا همین کاری که اینجی کردیم) و کلید اصلی مدل target و مدل source به عنوان کلید اصلی ترکیبی تو جدول C تعریف میکنه.
به جدول C که واسطه بین دو تا جدول ما هست junction table میگن. ولی اگه شما میخواید junction table تون یه سری column های بیشتری داشته باشه باس خودتون یه مدل تعریف کنید و بعد اونو به جای 'C' بدید (مثل این: C)
پس در مجموع اگه بخوای یه رابطه یک به یک بسازی باس از hasOne و belongsTo به صورت همزمان استفاده بکنی. و اگه یه رابطه یک به چند میخوای از hasMany به همراه belongsTo استفاده میتونی، یادت باشه اگه از hasMany به همراه hasOne برا ایجاد association یک به چند استفاده بکنی به ارور Cyclic dependency یا Dependency chain میخوری:
برا ایجاد رابطه چند به چند هم باس از belongsToMany استفاده بکنی. فقط تو این یه مورد باید through رو تو option هاش بدی ولی بقیه option هاش مثل onDelete و ... اختیاری هس و اگه ست نکنی مقدار پیشفرضش که No Action هس رو میگیره.
// posts M:N tags PostModel.belongsToMany(TagModel, { through: 'post_tags', onDelete: 'CASCADE' }); TagModel.belongsToMany(PostModel, { through: 'post_tags', onDelete: 'CASCADE' });
توی اینجا میتونی تنظیمات FK رو مشخص بکنی. مثلا اسم ستون، nullable بودن، مقدار پیشفرض رو مشخص بکنی
برا اینکه include رو تو sequelize بفهمید باس اول دو تا مفهوم رو که پایه ای هستن یاد بگیرید: Eager Loading و Lazy Loading.
تو Lazy Loading میگیم اگه واقعا دیتا های مرتبط رو هم لازم داری بگو تا برات fetch اش بکنیم. ولی Eager Loading اون طرف دیگه قضیه هس که میگه من همه چیو با یه کوئری خفن ولی گنده (همهی دیتا هایی که به نظرت لازمت میشه و بعدا لازمش داری) میام fetch میکنم. بزارید با مثال براتون نمایش بدمش:
// Lazy loading const post = await Post.findOne({ where: { slug: "Jack-Sparrow" } }); // Do whatever you want with post // Now we want post's writer const user = await post.getUser();
خب فک کنم الان دارید میفهمید وقتی نوشتم که فقط زمانی که بهش نیاز داشتید میای دیتای مورد نیازتو fetch میکنی. تو این مثال اول خود پستو fetch کردیم و بعدا که به اطلاعات فردی که این پستو نوشته نیاز پیدا کردیم اومدیم اطلاعاتش رو هم fetch کردیم.
ما از Lazy loading تو مواردی استفاده میکنیم که تحت یه شرایط خاصی میخواییم دیتا های مرتبط رو هم fetch کنیم و تو بعضی شرایط به اون دیتا ها نیاز نداریم. Lazy loading تو save کردن زمان و مموری به ما کمک میکنه.
این متد getUser توسط خود sequelize به مدل post اضافه شده و شما میتونید توسط اون اطلاعات کاربرو fetch کنید.
const users = await User.findAll({ include: { model: UserRole, where: { accessLevel: 2 } } });
همون جوری که میبینید تو این مثال همهی کاربرا رو بعلاوه اطلاعات role شون تو سیستم fetch کردیم. توجه کنید که اگه بخوای چند تا چیزو به صورت همزمان fetch کنی باس اینکار بکنی:
posts = await PostModel.findAll({ where: { isPublished: true }, include: [ { model: CategoryModel, attributes: ['title'], where: { title: categoryTitle } }, { model: CommentModel }, { model: UserModel, attributes: ['fullname', 'id'] } ] });
یعنی از [] برا اینکه چند تا چیزو با هم include کنی باس استفاده بکنی. حالا روش که forEach بزنی فیلدایی رو که برا مدلت تعریف کردی داری. خود sequelize میاد فیلدای اون مدلای دیگه رو به آبجکتی که برمیگردونه اضافه میکنه.
posts.forEach((post, i) => { // post.categories.forEach(category => { /* ... */ }); // post.title // post.user.fullname // post.comments.forEach(comment => { /* ... */ });
خب حالا بقیشو باس برید تو آپارات نگاه بکنید:)
لینک: https://www.aparat.com/v/Ryx3j