Skip to content

Update a record by using an instance method on one of the fields (one query) #3082

@shaiherman

Description

@shaiherman

Hi,

First off - sequelize has been a pleasure to work with. Been helping much on a project I'm working on. Digging around github, looks like LOTS of hard and mindful work has been put in. Thanks.

I was wondering if it was possible to use a Model's instance method in the updating of a specific row. The preference is to generate one update query (update... where...) and keep associated Model functionality, like creating a UUID, in the Model without replicating elsewhere. So doing a find first, then an update would allow me to use instance methods (or getters/setters) on the Model, but would be an example of two queries. I could also do an update() call with where clause, but would have to re-create the functionality in my model, like the generation of a UUID, and use that inside my update().

I'm using 2.0.0-rc8 with postgres.

Model:
I've simplified the Model here...

module.exports = function(sequelize, DataTypes) {
  var tableA = sequelize.define("tableA", {
    id: {
      type: DataTypes.UUID,
      primaryKey: true,
      defaultValue: DataTypes.UUIDV4,
    }
  }, {
    classMethods: {
      associate: function(models) {
        tableA.belongsTo(models.tableB);
      }
    },
    instanceMethods: {
      newUUID: function() {
        return uuid.v4();  // required sequelize's module dependency on node-uuid to enable this
      }
    }
  });

There are three ways I was trying to make this happen, and I'm probably just missing something...

1.Using the update method:

tableA.update({
      id: this.newUUID,
    }, {
      where: {
        tableB_id: 'some value'
      }
    }
  );

The problem is that 'primaryKey' is considered null and this violate a not-null constraint - my understanding is that Model instance methods, and getters/setters require an instance to be created first, hence the issue. I've observed this occurring with a field that is allowNull: false too.

2.Building to generate an instance method:

var tableUpdate = models.tableA.build({
    id: this.newUUID,
  }, {
    isNewRecord: false  // to make this an update and NOT a create
  });

This works in providing me access to an instance method or a getter/setter, however I can't figure out how to limit the update to a "where" on a foreign key field.

3.Creating a public function, outside sequelize, as a helper of sorts:

module.exports = function(sequelize, DataTypes) {
  var tableA = sequelize.define("tableA", {
    id: {
      type: DataTypes.UUID,
      primaryKey: true,
      defaultValue: DataTypes.UUIDV4,
    }
  }, {
    classMethods: {
      associate: function(models) {
        tokenA.belongsTo(models.tableB);
      }
    }
  });

  tableA.newUUID = function() {
    return uuid.v4();
  }

... then later on 

    tableA.update({
      id: tableA.newUUID,
    }, {
      where: {
        tableB_id: 'some value'
      }
    }
  );

This works, but its nature does not make it exclusive to a model's instance. Maybe its good enough - it opens the door for a model helper file.

If it's not possible to do such a thing with one query, is it reasonable to request an options.where for a build? Or possibly some other solution?

I may have overcomplicated things with my desire for one query vs two. I'm open to any suggestions/best-practices.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions