Skip to content

Commit 87049eb

Browse files
committed
and more sequelize
1 parent fa0766e commit 87049eb

File tree

5 files changed

+382
-6
lines changed

5 files changed

+382
-6
lines changed

rootfs_overlay/lkmc/nodejs/sequelize/association_many_to_many.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const user2Likes = await user2.getPosts({order: [['body', 'ASC']]})
7070
assert(user2Likes[0].body === 'post1');
7171
assert(user2Likes.length === 1);
7272

73-
// Same as get* but with the user ID instead of the model object.
73+
// Same as get but with the user ID instead of the model object.
7474
{
7575
const user0Likes = await Post.findAll({
7676
include: [{
@@ -84,6 +84,20 @@ assert(user2Likes.length === 1);
8484
assert(user0Likes.length === 2);
8585
}
8686

87+
// Yet another way that can be more useful in nested includes.
88+
{
89+
const user0Likes = (await User.findOne({
90+
where: {id: user0.id},
91+
include: [{
92+
model: Post,
93+
}],
94+
order: [[Post, 'body', 'ASC']],
95+
})).Posts
96+
assert(user0Likes[0].body === 'post0');
97+
assert(user0Likes[1].body === 'post1');
98+
assert(user0Likes.length === 2);
99+
}
100+
87101
// Get users that liked a given likes.
88102

89103
const post0Likers = await post0.getUsers({order: [['name', 'ASC']]})
@@ -96,9 +110,7 @@ assert(post1Likers[1].name === 'user2');
96110
assert(post1Likers.length === 2);
97111

98112
const post2Likers = await post2.getUsers({order: [['name', 'ASC']]})
99-
assert(post1Likers[0].name === 'user0');
100-
assert(post1Likers[1].name === 'user2');
101-
assert(post1Likers.length === 2);
113+
assert(post2Likers.length === 0);
102114

103115
// Autogenerated has* methods
104116

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#!/usr/bin/env node
2+
3+
// Two associations between two specific models. Requires us to use alias with `as:`
4+
// to disambiguate them.
5+
6+
const assert = require('assert');
7+
const path = require('path');
8+
9+
const { Sequelize, DataTypes } = require('sequelize');
10+
11+
const sequelize = new Sequelize({
12+
dialect: 'sqlite',
13+
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
14+
});
15+
16+
(async () => {
17+
18+
// Create the tables.
19+
const User = sequelize.define('User', {
20+
name: { type: DataTypes.STRING },
21+
}, {});
22+
const Post = sequelize.define('Post', {
23+
body: { type: DataTypes.STRING },
24+
}, {});
25+
26+
User.belongsToMany(Post, {through: 'UserLikesPost', as: 'likedPosts'});
27+
Post.belongsToMany(User, {through: 'UserLikesPost', as: 'likers'});
28+
29+
User.belongsToMany(Post, {through: 'UserFollowsPost', as: 'followedPosts'});
30+
Post.belongsToMany(User, {through: 'UserFollowsPost', as: 'followers'});
31+
32+
await sequelize.sync({force: true});
33+
34+
// Create some users and likes.
35+
36+
const user0 = await User.create({name: 'user0'})
37+
const user1 = await User.create({name: 'user1'})
38+
const user2 = await User.create({name: 'user2'})
39+
40+
const post0 = await Post.create({body: 'post0'});
41+
const post1 = await Post.create({body: 'post1'});
42+
const post2 = await Post.create({body: 'post2'});
43+
44+
// Autogenerated add* methods
45+
46+
// Setup likes and follows.
47+
await user0.addLikedPost(post0)
48+
await post1.addLikers([user0, user2])
49+
await user1.addFollowedPosts([post0, post1])
50+
await post1.addFollower(user2)
51+
52+
// Autogenerated get* methods
53+
54+
// Get likes by a user.
55+
56+
const user0Likes = await user0.getLikedPosts({order: [['body', 'ASC']]})
57+
assert(user0Likes[0].body === 'post0');
58+
assert(user0Likes[1].body === 'post1');
59+
assert(user0Likes.length === 2);
60+
61+
const user1Likes = await user1.getLikedPosts({order: [['body', 'ASC']]})
62+
assert(user1Likes.length === 0);
63+
64+
const user2Likes = await user2.getLikedPosts({order: [['body', 'ASC']]})
65+
assert(user2Likes[0].body === 'post1');
66+
assert(user2Likes.length === 1);
67+
68+
// Get users that liked a given post.
69+
70+
const post0Likers = await post0.getLikers({order: [['name', 'ASC']]})
71+
assert(post0Likers[0].name === 'user0');
72+
assert(post0Likers.length === 1);
73+
74+
const post1Likers = await post1.getLikers({order: [['name', 'ASC']]})
75+
assert(post1Likers[0].name === 'user0');
76+
assert(post1Likers[1].name === 'user2');
77+
assert(post1Likers.length === 2);
78+
79+
const post2Likers = await post2.getLikers({order: [['name', 'ASC']]})
80+
assert(post2Likers.length === 0);
81+
82+
// Get follows by a user.
83+
84+
const user0Follows = await user0.getFollowedPosts({order: [['body', 'ASC']]})
85+
assert(user0Follows.length === 0);
86+
87+
const user1Follows = await user1.getFollowedPosts({order: [['body', 'ASC']]})
88+
assert(user1Follows[0].body === 'post0');
89+
assert(user1Follows[1].body === 'post1');
90+
assert(user1Follows.length === 2);
91+
92+
const user2Follows = await user2.getFollowedPosts({order: [['body', 'ASC']]})
93+
assert(user2Follows[0].body === 'post1');
94+
assert(user2Follows.length === 1);
95+
96+
// Get users that followed a given post.
97+
98+
const post0Followers = await post0.getFollowers({order: [['name', 'ASC']]})
99+
assert(post0Followers[0].name === 'user1');
100+
assert(post0Followers.length === 1);
101+
102+
const post1Followers = await post1.getFollowers({order: [['name', 'ASC']]})
103+
assert(post1Followers[0].name === 'user1');
104+
assert(post1Followers[1].name === 'user2');
105+
assert(post1Followers.length === 2);
106+
107+
const post2Followers = await post2.getFollowers({order: [['name', 'ASC']]})
108+
assert(post2Followers.length === 0);
109+
110+
// Same as getLikedPosts but with the user ID instead of the model object.
111+
{
112+
const user0Likes = await Post.findAll({
113+
include: [{
114+
model: User,
115+
as: 'likers',
116+
where: {id: user0.id},
117+
}],
118+
order: [['body', 'ASC']],
119+
})
120+
assert(user0Likes[0].body === 'post0');
121+
assert(user0Likes[1].body === 'post1');
122+
assert(user0Likes.length === 2);
123+
}
124+
125+
// Yet another way that can be more useful in nested includes.
126+
{
127+
const user0Likes = (await User.findOne({
128+
where: {id: user0.id},
129+
include: [{
130+
model: Post,
131+
as: 'likedPosts',
132+
}],
133+
order: [[{model: Post, as: 'likedPosts'}, 'body', 'ASC']],
134+
})).likedPosts
135+
assert(user0Likes[0].body === 'post0');
136+
assert(user0Likes[1].body === 'post1');
137+
assert(user0Likes.length === 2);
138+
}
139+
140+
await sequelize.close();
141+
})();
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env node
2+
3+
const assert = require('assert');
4+
const path = require('path');
5+
6+
const { Sequelize, DataTypes } = require('sequelize');
7+
8+
const sequelize = new Sequelize({
9+
dialect: 'sqlite',
10+
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
11+
});
12+
13+
(async () => {
14+
15+
// Create the tables.
16+
const User = sequelize.define('User', {
17+
name: { type: DataTypes.STRING },
18+
}, {});
19+
const Post = sequelize.define('Post', {
20+
body: { type: DataTypes.STRING },
21+
}, {});
22+
User.hasMany(Post);
23+
Post.belongsTo(User);
24+
await sequelize.sync({force: true});
25+
26+
// Create data.
27+
const users = await User.bulkCreate([
28+
{name: 'user0'},
29+
{name: 'user1'},
30+
{name: 'user2'},
31+
{name: 'user3'},
32+
])
33+
34+
const posts = await Post.bulkCreate([
35+
{body: 'body00', UserId: users[0].id},
36+
{body: 'body01', UserId: users[0].id},
37+
{body: 'body10', UserId: users[1].id},
38+
{body: 'body11', UserId: users[1].id},
39+
{body: 'body20', UserId: users[2].id},
40+
{body: 'body21', UserId: users[2].id},
41+
{body: 'body30', UserId: users[3].id},
42+
{body: 'body31', UserId: users[3].id},
43+
])
44+
45+
// Get user from post and vice versa.
46+
47+
const user0Posts = await users[0].getPosts({order: [['body', 'ASC']]})
48+
assert(user0Posts[0].body === 'body00')
49+
assert(user0Posts[1].body === 'body01')
50+
assert(user0Posts.length === 2)
51+
52+
const user1Posts = await users[1].getPosts({order: [['body', 'ASC']]})
53+
assert(user1Posts[0].body === 'body10')
54+
assert(user1Posts[1].body === 'body11')
55+
assert(user1Posts.length === 2)
56+
57+
const post00User = await posts[0].getUser()
58+
assert(post00User.name === 'user0')
59+
60+
const post01User = await posts[1].getUser()
61+
assert(post01User.name === 'user0')
62+
63+
const post10User = await posts[2].getUser()
64+
assert(post10User.name === 'user1')
65+
66+
const post11User = await posts[3].getUser()
67+
assert(post11User.name === 'user1')
68+
69+
await sequelize.close();
70+
})();
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env node
2+
3+
// Two associations between two models: posts
4+
// now have the author, and a mandatory reviewer.
5+
// Requires us to use as do disambiguate them.
6+
7+
const assert = require('assert');
8+
const path = require('path');
9+
10+
const { Sequelize, DataTypes } = require('sequelize');
11+
12+
const sequelize = new Sequelize({
13+
dialect: 'sqlite',
14+
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
15+
define: {
16+
timestamps: false
17+
},
18+
});
19+
20+
(async () => {
21+
22+
// Create the tables.
23+
const User = sequelize.define('User', {
24+
name: { type: DataTypes.STRING },
25+
}, {});
26+
const Post = sequelize.define('Post', {
27+
body: { type: DataTypes.STRING },
28+
}, {});
29+
30+
// TODO possible without specifying foreignKey? Feels like duplication.
31+
// But without it, hasMany creates a column called UserId, in addition
32+
// to the desired authorId, and then bad things happen.
33+
User.hasMany(Post, {as: 'authoredPosts', foreignKey: 'authorId'});
34+
Post.belongsTo(User, {as: 'author', foreignKey: 'authorId'});
35+
36+
User.hasMany(Post, {as: 'reviewedPosts', foreignKey: 'reviewerId'});
37+
Post.belongsTo(User, {as: 'reviewer', foreignKey: 'reviewerId'});
38+
await sequelize.sync({force: true});
39+
40+
// Create data.
41+
const users = await User.bulkCreate([
42+
{name: 'user0'},
43+
{name: 'user1'},
44+
{name: 'user2'},
45+
{name: 'user3'},
46+
])
47+
48+
const posts = await Post.bulkCreate([
49+
{body: 'body00', authorId: users[0].id, reviewerId: users[0].id},
50+
{body: 'body01', authorId: users[0].id, reviewerId: users[1].id},
51+
{body: 'body10', authorId: users[1].id, reviewerId: users[2].id},
52+
{body: 'body11', authorId: users[1].id, reviewerId: users[3].id},
53+
{body: 'body20', authorId: users[2].id, reviewerId: users[0].id},
54+
{body: 'body21', authorId: users[2].id, reviewerId: users[1].id},
55+
{body: 'body30', authorId: users[3].id, reviewerId: users[2].id},
56+
{body: 'body31', authorId: users[3].id, reviewerId: users[3].id},
57+
])
58+
59+
// Get user from post and vice versa.
60+
61+
const user0AuthoredPosts = await users[0].getAuthoredPosts()
62+
assert(user0AuthoredPosts[0].body === 'body00')
63+
assert(user0AuthoredPosts[1].body === 'body01')
64+
assert(user0AuthoredPosts.length === 2)
65+
66+
const user1AuthoredPosts = await users[1].getAuthoredPosts()
67+
assert(user1AuthoredPosts[0].body === 'body10')
68+
assert(user1AuthoredPosts[1].body === 'body11')
69+
assert(user1AuthoredPosts.length === 2)
70+
71+
const user0ReviewedPosts = await users[0].getReviewedPosts()
72+
assert(user0ReviewedPosts[0].body === 'body00')
73+
assert(user0ReviewedPosts[1].body === 'body20')
74+
assert(user0ReviewedPosts.length === 2)
75+
76+
const user1ReviewedPosts = await users[1].getReviewedPosts()
77+
assert(user1ReviewedPosts[0].body === 'body01')
78+
assert(user1ReviewedPosts[1].body === 'body21')
79+
assert(user1ReviewedPosts.length === 2)
80+
81+
assert((await posts[0].getAuthor()).name === 'user0')
82+
assert((await posts[1].getAuthor()).name === 'user0')
83+
assert((await posts[2].getAuthor()).name === 'user1')
84+
assert((await posts[3].getAuthor()).name === 'user1')
85+
86+
assert((await posts[0].getReviewer()).name === 'user0')
87+
assert((await posts[1].getReviewer()).name === 'user1')
88+
assert((await posts[2].getReviewer()).name === 'user2')
89+
assert((await posts[3].getReviewer()).name === 'user3')
90+
91+
// Same as getAuthoredPosts but with the user ID instead of the model object.
92+
{
93+
const user0AuthoredPosts = await Post.findAll({
94+
include: [{
95+
model: User,
96+
// We need the `as` here to disambiguate.
97+
as: 'author',
98+
where: {id: users[0].id},
99+
}],
100+
order: [['body', 'ASC']],
101+
})
102+
assert(user0AuthoredPosts[0].body === 'body00');
103+
assert(user0AuthoredPosts[1].body === 'body01');
104+
assert(user0AuthoredPosts.length === 2);
105+
}
106+
107+
// Yet another way that can be more useful in nested includes.
108+
{
109+
const user0AuthoredPosts = (await User.findOne({
110+
where: {id: users[0].id},
111+
include: [{
112+
model: Post,
113+
as: 'authoredPosts',
114+
}],
115+
order: [[{model: Post, as: 'authoredPosts'}, 'body', 'ASC']],
116+
})).authoredPosts
117+
assert(user0AuthoredPosts[0].body === 'body00');
118+
assert(user0AuthoredPosts[1].body === 'body01');
119+
assert(user0AuthoredPosts.length === 2);
120+
}
121+
122+
await sequelize.close();
123+
})();

0 commit comments

Comments
 (0)