actionhero / ah-sequelize-plugin

sequelize plugin for actionhero
36 stars 23 forks source link

Public Class Fields in Sequelize V6 #719

Open mfvargo opened 1 month ago

mfvargo commented 1 month ago

Example models in this plugin will not work correctly with Sequelize v6 as per https://sequelize.org/docs/v6/core-concepts/model-basics/#caveat-with-public-class-fields

Caveat with Public Class Fields Adding a Public Class Field with the same name as one of the model's attribute is going to cause issues. Sequelize adds a getter & a setter for each attribute defined through Model.init. Adding a Public Class Field will shadow those getter and setters, blocking access to the model's actual data.

The models need a declare before the field name so the type can be specified without colliding with the inferred model getter/setter from the Sequelize base Model.

@Table({ tableName: "users", paranoid: true })
export class User extends Model {
  saltRounds = 10;

  @Column({ primaryKey: true })
  guid: string;

  @AllowNull(false)
  @Column
  firstName: string;

...

should be

@Table({ tableName: "users", paranoid: true })
export class User extends Model {
  saltRounds = 10;

  @Column({ primaryKey: true })
  declare guid: string;
  ^^^^^^
  @AllowNull(false)
  @Column
  declare firstName: string;
  ^^^^^^
...
evantahler commented 1 month ago

Looks like a conflict between seqelize and sequelize-typescript. I wonder if we don't need sequelize-typescript any more?

mfvargo commented 1 month ago

I did a quick attempt by

  1. comment out the @Column line for a simple fields called name on one of my models. That caused other spots in the model definition to crash when trying to access thing.name as undefined.
  2. I then tried to just comment out the @Column before the declare but left the declare in. This let me access thing.name but it was shadowing the setter/getter from sequelize so the value was not getting saved to db.

I will try to define a model without sequelize-typescript to see if I still get typed returns etc. I have to pick an easy one without many foreign keys and hooks.