sequelize-typescript
sequelize-typescript copied to clipboard
Can't define scopes in separate variables/files to use in the @DefaultScope and @Scope decorators
Versions
- sequelize: 6.4.0
- sequelize-typescript: 2.0.0
- typescript: 4.1.3
I'm submitting a ... [x] bug report [x] feature request
Actual behavior: I am unable to use the decorators to define scopes for one of my models. It has quite a few relations and nested includes, so I have delcared them in a separate file
// ModelAScopes.ts
const defaultScope = {
include: [
{
model: ModelB,
as: 'modelBs'
}
]
}
// ModelA.ts
@DefaultScope(() => defaultScope)
@Table({ tableName: 'model_a' })
export defulat lass ModelA extends Model {
@PrimaryKey
@Column(DataType.STRING(36))
public uuid!: string;
@HasMany(() => ModelB)
modelBs!: ModelB[];
}
// ModelB.ts
@Table({ tableName: 'model_b' })
export default class ModelBp extends Model {
@PrimaryKey
@AutoIncrement
@Column(DataType.BIGINT)
public id!: number;
@ForeignKey(() => ModelA)
@Column({
type: DataType.STRING(36),
field: 'model_a_uuid',
onDelete: 'cascade',
})
public modelAUUID!: string;
@BelongsTo(() => ModelA)
public quote!: ModelA;
}
I get the following error when running code that touches this model
Include unexpected. Element has to be either a Model, an Association or an object.
Using the exact same scope definitions, the following way of adding the scopes to the model works.
sequelize.addModels([...,ModelA, ModelB]);
ModelA.addScope('defaultScope', defaultScope, { override: true });
Expected behavior: I expect the behavior to be the same regardless of where I create the scopes.
It would be nice to be able to create the scope definitions elsewhere and then pass them into the decorators. For example, I am combining a couple different scopes to avoid duplicate code, like this
const defaultScope = { include: [ModelB };
const apiScope= { attributes: { exclude: 'privateField' }, ...defaultScope }
I think I figured it out.
Each hook must be a static method. Multiple hooks can be attached to a single method, and you can define multiple methods for a given hook.
It appears that by defining the hooks in a separate file, or even in a variable does not work since it doesn't register ModelB
as a model
If it's still relevant, I figured out a way to make it work. I had the same issue with hooks. The key is to export a function that returns the scope definition rather that the object itself. So, this works:
// ModelAScopes.ts
const getDefaultScope = () => ({
include: [
{
model: ModelB,
as: 'modelBs'
}
]
})
// ModelA.ts
@DefaultScope(() => getDefaultScope())
@Table({ tableName: 'model_a' })
I think it has to do with how node resolves circular dependencies or something...
@Papooch your solution works 👏