Whats the problem that should been solved?
It should be possible to define includes dynamically when retrieving or writing data.
Current situation
Selecting data including related data:
// Find all projects with a least one task where task.state === project.state
Project.findAll({
include: [{
model: Task,
where: { state: Sequelize.col('project.state') }
}]
})
from sequelize docs
Specifying attributes work like this:
Model.findAll({
attributes: ['foo', 'bar']
});
from sequelize docs
Writing entities including related models:
return Product.create({
title: 'Chair',
user: {
first_name: 'Mick',
last_name: 'Broadstone',
addresses: [{
type: 'home',
line_1: '100 Main St.',
city: 'Austin',
state: 'TX',
zip: '78704'
}]
}
}, {
include: [{
association: Product.User,
include: [ User.Addresses ]
}]
});
from sequelize docs
Idea
In sequelize-typescript related data is described through a normal property of a class with a HasMany/HasOne/BelongsTo/BelongsToMany decorator:
class User extends Model<User> {
/* β¦ */
@BelongsToMany(User, UserFollower)
followers: User[];
}
How to find data and get included entities (semi)automatically:
So instead of setting an include option for related data, the attribute key, which describes the related data, could be defined in the attribute options like so
User.findAll({
attributes: ['followers']
})
Additionally the attributes of the related Model can be defined like:
User.findAll({
attributes: ['followers.name']
})
(Probably a flag should be set somewhere)
How to write data and set includes automatically:
So instead of explicitly specifying includes when writing, the related data can be detected by its attribute key.
Question.create({
text: "Which one is the better star wars movie?",
answers: [
{text: "Rogue One: A Star Wars Story"},
{text: "Star Wars: The Force Awakens"}
]
}, {inferIncludes: true})
To prevent unexpected behavior a flag like inferIncludes
should be set to true.
Downsides
- sequelize-typescript changes behavior of sequelize (one can argue, that we already doing this on the one or other feature)
Reminder
When implementing think of
attributes: {exclude: ["foo"]}
- scopes