ID photo of Ciro Santilli taken in 2013 right eyeCiro Santilli OurBigBook logoOurBigBook.com  Sponsor 中国独裁统治 China Dictatorship 新疆改造中心、六四事件、法轮功、郝海东、709大抓捕、2015巴拿马文件 邓家贵、低端人口、西藏骚乱
nodejs/sequelize/many_to_many_super.js
#!/usr/bin/env node
// https://cirosantilli.com/sequelize-example
const assert = require('assert');
const path = require('path');
const { DataTypes, Op } = require('sequelize');
const common = require('./common')
const sequelize = common.sequelize(
  __filename, process.argv[2],
  { define: { timestamps: false } }
)
;(async () => {
// Create the tables.

const User = sequelize.define('User', {
  name: { type: DataTypes.STRING },
});
const Post = sequelize.define('Post', {
  body: { type: DataTypes.STRING },
});
const UserLikesPost = sequelize.define('UserLikesPost')
UserLikesPost.belongsTo(User)
User.hasMany(UserLikesPost)
UserLikesPost.belongsTo(Post)
Post.hasMany(UserLikesPost)
User.belongsToMany(Post, { through: UserLikesPost });
Post.belongsToMany(User,{ through: UserLikesPost });

await sequelize.sync({ force: true });

async function reset() {
  await sequelize.truncate({ cascade: true })
  const user0 = await User.create({ name: 'user0' })
  const user1 = await User.create({ name: 'user1' })
  const user2 = await User.create({ name: 'user2' })
  const post0 = await Post.create({ body: 'post0' })
  const post1 = await Post.create({ body: 'post1' })
  const post2 = await Post.create({ body: 'post2' })
  await user0.addPost(post0)
  await post1.addUsers([user0, user2])
  return [user0, user1, user2, post0, post1, post2]
}
let [user0, user1, user2, post0, post1, post2] = await reset()
let rows;

// Sanity test.
rows = await post0.getUsers({order: [['name', 'ASC']]})
assert.strictEqual(rows[0].name, 'user0');
assert.strictEqual(rows.length, 1);
rows = await post1.getUsers({order: [['name', 'ASC']]})
assert.strictEqual(rows[0].name, 'user0');
assert.strictEqual(rows[1].name, 'user2');
assert.strictEqual(rows.length, 2);
rows = await post2.getUsers({order: [['name', 'ASC']]})
assert.strictEqual(rows.length, 0);

// Now stuff that we weren't able to do without super. Is it possible without??

// TODO Get all posts, and also determine if user2 likes each of of them or not.
// by doing LEFT OUTER JOIN.
rows = await Post.findAll({
  include: [{
    model: UserLikesPost,
    where: { UserId: user2.id },
    required: false,
    include: [{
      model: User
    }]
  }],
  order: [['body', 'ASC']],
})
assert.strictEqual(rows[0].body, 'post0');
assert.strictEqual(rows[0].UserLikesPosts.length, 0);
assert.strictEqual(rows[1].body, 'post1');
assert.strictEqual(rows[1].UserLikesPosts.length, 1);
assert.strictEqual(rows[2].body, 'post2');
assert.strictEqual(rows[2].UserLikesPosts.length, 0);
assert.strictEqual(rows.length, 3);

})().finally(() => { return sequelize.close() });