title: Sequelize polymorphic many to many - `add` mixin not working
body: <p>I have a many-to-many polymorphic association setup for customer surveys. The issue that I have run into is when using the <code>add</code> mixin on the model instance of <code>Survey</code>. If the joining table already has an item with the <code>surveyed</code> field equal to the <code>id</code> of the new surveyable, it gets overwritten.</p>
  <p><code>survey</code> table:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>id</th>
  <th>name</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>1</td>
  <td>'Customer Survey'</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p><code>scheduled_sessions</code> table:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>id</th>
  <th>appointment_data</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>10</td>
  <td>{ &quot;someData&quot; : [] }</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p><code>service_provider</code> table:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>id</th>
  <th>name</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>10</td>
  <td>Joe Doe</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p><code>survey_surveyable</code> table:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>survey</th>
  <th>surveyable</th>
  <th>surveyed</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>1</td>
  <td>serviceProvider</td>
  <td>10</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p>When I <code>add</code> a scheduled session that happens to have the same id as a service provider, the join table row is overwritten:</p>
  <pre class="lang-js prettyprint-override"><code>const surveyInstance = await DB.Survey.findByPk(1);
  const scheduledSessionInstance = await DB.ScheduledSession.findByPk(10);
  
  surveyInstance.addScheduledSession(
    scheduledSessionInstance,
    { through: { surveyable: &quot;scheduledSession&quot; } }
  );
  
  return surveyInstance.save();
  </code></pre>
  <p>This is the SQL queries that sequelize runs:</p>
  <pre class="lang-sql prettyprint-override"><code>SELECT &quot;id&quot;, &quot;name&quot;
    FROM &quot;surveys&quot; AS &quot;Survey&quot;
    WHERE &quot;Survey&quot;.&quot;id&quot; = 1;
  
  SELECT &quot;id&quot;, &quot;appointment_data&quot; AS &quot;appointmentData&quot;
    FROM &quot;scheduled_sessions&quot; AS &quot;ScheduledSession&quot;
    WHERE &quot;ScheduledSession&quot;.&quot;id&quot; = 10;
  
  SELECT &quot;survey&quot;, &quot;surveyable&quot;, &quot;surveyed&quot;
    FROM &quot;survey_surveyable&quot; AS &quot;SurveySurveyable&quot;
    WHERE
      &quot;SurveySurveyable&quot;.&quot;survey&quot; = 1 AND
      &quot;SurveySurveyable&quot;.&quot;surveyed&quot; IN (10);
  
  UPDATE &quot;survey_surveyable&quot;
    SET &quot;surveyable&quot;=$1
    WHERE
      &quot;survey&quot; = $2 AND
      &quot;surveyed&quot; = $3
  </code></pre>
  <p>Since both the scheduled session and the service provider have <code>id=10</code>, the service provider row in the join table is overwritten resulting in:</p>
  <p><code>survey_surveyable</code> table:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>survey</th>
  <th>surveyable</th>
  <th>surveyed</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>1</td>
  <td>scheduledSession</td>
  <td>10</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p>where it should have been:</p>
  <p><code>survey_surveyable</code> table:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>survey</th>
  <th>surveyable</th>
  <th>surveyed</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>1</td>
  <td>serviceProvider</td>
  <td>10</td>
  </tr>
  <tr>
  <td>1</td>
  <td>scheduledSession</td>
  <td>10</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p>Is this a sequelize issue, or am I using the <code>add</code> mixin incorrectly?</p>
  <h2>My models:</h2>
  <p>Survey.js:</p>
  <pre class="lang-js prettyprint-override"><code>module.exports = (sequelize, DataTypes) =&gt; {
    class Survey extends sequelize.Sequelize.Model {};
  
    Survey.init(
      {
        id: {
          type: DataTypes.INTEGER,
          autoIncrement: true,
          allowNull: false,
          primaryKey: true
        },
        name: {
          type: DataTypes.STRING,
          allowNull: false
        }
      },
      {
        timestamps: false,
        tableName: &quot;surveys&quot;,
        sequelize
      }
    );
  
    Survey.associate = (models) =&gt; {
      Survey.belongsToMany(models.ScheduledSession, {
        through: {
          model: models.SurveySurveyable,
          unique: false
        },
        foreignKey: &quot;survey&quot;,
        constraints: false
      });
    };
  
    return Survey;
  };
  </code></pre>
  <p>ScheduledSession.js:</p>
  <pre class="lang-js prettyprint-override"><code>module.exports = (sequelize, DataTypes) =&gt; {
    class ScheduledSession extends sequelize.Sequelize.Model {};
  
    ScheduledSession.init(
      {
        id: {
          type: DataTypes.INTEGER,
          autoIncrement: true,
          allowNull: false,
          primaryKey: true
        }
        appointmentData: {
          type: DataTypes.JSONB,
          allowNull: false,
          field: &quot;appointment_data&quot;
        }
      },
      {
        paranoid: true,
        tableName: &quot;scheduled_sessions&quot;,
        sequelize
      }
    );
  
    ScheduledSession.associate = (models) =&gt; {
      ScheduledSession.belongsToMany(models.Survey, {
        through: {
          model: models.SurveySurveyable,
          unique: false,
          scope: {
            surveyable: &quot;scheduledSession&quot;
          }
        },
        foreignKey: &quot;surveyed&quot;,
        constraints: false
      });
    };
  
    return ScheduledSession;
  };
  </code></pre>
  <p>ServiceProvider.js:</p>
  <pre class="lang-js prettyprint-override"><code>module.exports = (sequelize, DataTypes) =&gt; {
    class ServiceProvider extends sequelize.Sequelize.Model {};
  
    ServiceProvider.init(
      {
        id: {
          type: DataTypes.INTEGER,
          autoIncrement: true,
          allowNull: false,
          primaryKey: true
        }
        name: {
          type: DataTypes.STRING,
          allowNull: false
        }
      },
      {
        paranoid: true,
        tableName: &quot;service_provider&quot;,
        sequelize
      }
    );
  
    ServiceProvider.associate = (models) =&gt; {
      ServiceProvider.belongsToMany(models.Survey, {
        through: {
          model: models.SurveySurveyable,
          unique: false,
          scope: {
            surveyable: &quot;serviceProvider&quot;
          }
        },
        foreignKey: &quot;surveyed&quot;,
        constraints: false
      });
    };
  
    return ServiceProvider;
  </code></pre>
  <p>SurveySurveyable.js:</p>
  <pre class="lang-js prettyprint-override"><code>module.exports = (sequelize, DataTypes) =&gt; {
    class SurveySurveyable extends sequelize.Sequelize.Model {};
  
    SurveySurveyable.init(
      {
        survey: {
          type: DataTypes.INTEGER,
          allowNull: false,
          primaryKey: true
        },
        surveyable: {
          type: DataTypes.STRING,
          allowNull: false,
          primaryKey: true
        },
        surveyed: {
          type: DataTypes.INTEGER,
          allowNull: false,
          primaryKey: true,
          constraints: false
        }
      },
      {
        timestamps: false,
        tableName: &quot;survey_surveyable&quot;,
        sequelize,
        freezeTableName: true
      }
    );
  
    return SurveySurveyable;
  };
  
  </code></pre>