sequelize-typescript icon indicating copy to clipboard operation
sequelize-typescript copied to clipboard

Update a model's association using the model.$set() function not working

Open she-WritesCode opened this issue 3 years ago • 1 comments

Issue

I'm trying to update a model's association using the model.$set() function however I keep getting this err "SequelizeDatabaseError: Truncated incorrect DOUBLE value: '[object Object]"

Versions

  • sequelize: 6.6.2
  • sequelize-typescript: 2.1.0
  • typescript: 4.4.4

Issue type

  • [x] bug report
  • [ ] feature request

Actual behavior

I have two models Invoice and InvoiceItem. An Invoice has many InvoiceItems. An InvoiceItem belongs to an Invoice

I'm using the $set function to update the Invoice's InvoiceItem. and I am getting this error

{
  "name": "SequelizeDatabaseError",
  "parent": {
    "code": "ER_TRUNCATED_WRONG_VALUE",
    "errno": 1292,
    "sqlState": "22007",
    "sqlMessage": "Truncated incorrect DOUBLE value: '[object Object]'",
    "sql": "UPDATE `invoice_items` SET `invoice_id`=?,`updated_at`=? WHERE `id` IN ('[object Object]')",
    "parameters": [
      11,
      "2021-10-28 09:18:17"
    ]
  },
  "original": {
    "code": "ER_TRUNCATED_WRONG_VALUE",
    "errno": 1292,
    "sqlState": "22007",
    "sqlMessage": "Truncated incorrect DOUBLE value: '[object Object]'",
    "sql": "UPDATE `invoice_items` SET `invoice_id`=?,`updated_at`=? WHERE `id` IN ('[object Object]')",
    "parameters": [
      11,
      "2021-10-28 09:18:17"
    ]
  },
  "sql": "UPDATE `invoice_items` SET `invoice_id`=?,`updated_at`=? WHERE `id` IN ('[object Object]')",
  "parameters": [
    11,
    "2021-10-28 09:18:17"
  ]
}

It seems like the $set function doesn't work well with Array of Invoice Items.

Expected behavior

to be able to update the Invoice's InvoiceItem using, the Invoice.$set function

Steps to reproduce

const param = {
    "id": 11,
    "invoiceNumber": "907",
    "userId": 4,
    "businessId": 57,
    "businessCustomerId": 57,
    "discountPercent": 0,
    "invoiceDate": "2021-10-14",
    "invoiceDueDate": "2021-10-14",
    "notes": "pay into Access Bank 071648488",
    "subTotal": 70000,
    "taxPercent": 0,
    "total": 70000,
    "shippingAddress": null,
    "theme": "",
    "paid": "NO",
    "business_customer_id": 57,
    "business_id": 57,
    "user_id": 4,
    "items": [
        {
            "id": 19,
            "productId": 54,
            "invoiceId": 11,
            "additionalDescription": "",
            "amount": 0,
            "description": "8 pages and a blog with training for staff members",
            "orderIndex": 0,
            "quantity": 2,
            "unitPrice": 70000,
            "createdAt": "2021-10-14T10:58:39.000Z",
            "updatedAt": "2021-10-14T10:58:39.000Z"
        }
    ]
};

await invoice.update(params);
await invoice.$set("items", params.items as Array<InvoiceItem>);

Related code

// Invoice model
@Table({
	tableName: "invoices",
	underscored: true,
})
export default class Invoice extends Model<InvoiceAttributes> implements InvoiceAttributes {
	@Column
	public invoiceNumber: string;

	@ForeignKey(() => User)
	@Column
	public userId: number;

	@ForeignKey(() => Business)
	@Column
	public businessId: number;

	@ForeignKey(() => BusinessCustomer)
	@Column
	public businessCustomerId: number;

	@Column(DataType.DATEONLY)
	public invoiceDate: Date;

	@Column(DataType.DATEONLY)
	public invoiceDueDate: Date;

	@Column(DataType.TEXT)
	public notes: string;

	@Column
	public subTotal: number;

	@Column(DataType.FLOAT)
	public taxPercent: number;

	@Column(DataType.FLOAT)
	public total: number;

	@Column
	public shippingAddress: string;

	@Column
	public theme: string;

	@Default("NO")
	@Column(DataType.ENUM("NO", "YES")) // ..instead of true | false because of query string for filtering
	public paid: "NO" | "YES";

	@BelongsTo(() => BusinessCustomer, "business_customer_id")
	public businessCustomer: BusinessCustomer;

	@BelongsTo(() => Business, "business_id")
	public business: Business;

	@BelongsTo(() => User, "user_id")
	public user: User;

	@HasMany(() => InvoiceItem)
	public items: Array<InvoiceItem>;

	@CreatedAt
	public createdAt: Date;

	@UpdatedAt
	public updatedAt: Date;
}

// InvoiceItem Model
@Table({
	tableName: "invoice_items",
	underscored: true,
})
export class InvoiceItem extends Model<InvoiceItemAttributes> implements InvoiceItemAttributes {
	@Column
	public productId: number;

	@ForeignKey(() => Invoice)
	@Column
	public invoiceId: number;

	@Default("")
	@Column
	public additionalDescription: string;

	@Column
	public amount: number;

	@Default("")
	@Column
	public description: string;

	@Column
	public orderIndex: number;

	@Column
	public quantity: number;

	@Column
	public unitPrice: number;
}


she-WritesCode avatar Oct 28 '21 11:10 she-WritesCode

I have the same issue. I have this piece of code. It updates the role's name but not the permissions on that role:

const role = await Role.findByPk(id)
if(!role){
	throw new Error("role not found")
}
await role.update({
	name: form.name,
})
await role.$set('permissions', form.permissions.map(permission => RolePermission.build({permission})))

Models:

@Table
export class Role extends Model {
	@PrimaryKey
	@Column({type: DataType.UUID, defaultValue: DataType.UUIDV4})
	declare id: string

	@Column
	name: string

	@Column
	account_id: string

	@CreatedAt
	created_at: Date

	@UpdatedAt
	updated_at: Date

	@HasMany(() => RolePermission, {foreignKey: 'role_id'})
	permissions: RolePermission[]
}


@Table({tableName: 'role_permission'})
export class RolePermission extends Model {
	@PrimaryKey
	@Column({type: DataType.UUID, defaultValue: DataType.UUIDV4})
	declare id: string

	@Column
	permission: string

	@CreatedAt
	created_at: Date

	@UpdatedAt
	updated_at: Date

	@BelongsTo(() => Role, {foreignKey: 'role_id'})
	role: Role
}

IonelLupu avatar Sep 06 '22 17:09 IonelLupu