-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Description
What are you doing?
I am testing with a minimal example whether or not scopes' includes are shallowly merged, as the documentation claims: limit, offset, order, paranoid, lock and raw are overwritten, while where and include are shallowly merged. (source: http://docs.sequelizejs.com/manual/tutorial/scopes.html)
const Sequelize = require("sequelize");
const sequelize = new Sequelize({ dialect: "sqlite", storage: "db.sqlite" });
const Foo = sequelize.define("foo", { name: Sequelize.STRING }, { timestamps: false });
const Bar = sequelize.define("bar", { name: Sequelize.STRING }, { timestamps: false });
Foo.hasMany(Bar, { foreignKey: "fooId" });
Foo.addScope("testScope", {
include: [{
model: Bar,
where: {
name: "bar1"
}
}]
});
sequelize.sync({ force: true })
.then(() => Foo.create({ name: "foo1" }))
.then(foo1 => Bar.create({ name: "bar1", fooId: foo1.id }))
.then(() => Foo.create({ name: "foo2" }))
.then(foo2 => Bar.create({ name: "bar2", fooId: foo2.id }))
.then(() => Foo.scope("testScope").findAll({
include: [{
model: Bar,
attributes: { exclude: ["name"] }
}]
}))
.then(result => console.log(JSON.stringify(result, null, 4)));What do you expect to happen?
I expected the scope to be merged with the findAll options, which should yield the following output:
[
{
"id": 1,
"name": "foo1",
"bars": [
{
"id": 1,
"fooId": 1
}
]
}
]What is actually happening?
The output was:
[
{
"id": 1,
"name": "foo1",
"bars": [
{
"id": 1,
"fooId": 1
}
]
},
{
"id": 2,
"name": "foo2",
"bars": [
{
"id": 2,
"fooId": 2
}
]
}
]Clearly, the scope was completely overwritten by the findAll options.
I wanted my code to behave exactly as if I had called the following:
Foo.scope("testScope").findAll({
include: [{
model: Bar,
where: {
name: "bar1"
},
attributes: { exclude: ["name"] }
}]
})Dialect: sqlite (sqlite3 v3.1.13)
Dialect version: 3.1.13
Sequelize version: 4.33.4
Tested with latest release: Yes
Note: if somehow this is the correct behavior, honestly the docs should be clarified. The include field is an array of objects, and "shallowly merging" an array of objects is not perfectly clear, does it mean that the arrays are concatenated? I hope not. I understand that the behavior I'm expecting is not trivial to code, but if the documentation claims it, it should do it. My understanding of "shallowly merging" in this context would be that the objects in the include arrays are "matched" to each other based on the "model-as" pairs, shallowly merging the other fields (and hopefully, recursively, since I could have nested includes in my scopes).
Thank you very much in advance, sequelize has been very useful so far 😁