sql >> Databáze >  >> RDS >> PostgreSQL

Asociace v sequelize nefungují tak, jak bylo zamýšleno

Problémů je mnoho. Pokusím se je řešit postupně.

1) Modely Ve výchozím nastavení, pokud nedeklarujete primaryKey , pak sequelize automaticky přidá id sloupec pro vás. Tedy legId není užitečný sloupec.

Pokud navíc přiřadíte model, foreignKey reference je přidána za vás, tedy pawId by neměl být deklarován.

Tedy Legs.js by měl být upraven na:

module.exports = (sequelize, DataTypes) => {
  var Leg = sequelize.define('Leg', {
    originalValue: DataTypes.JSON,
    newValue: DataTypes.JSON,
    objectId: DataTypes.INTEGER // not entirely sure what this is 
  })
  Leg.associate = function (models) {
    // associations
  }
  return Leg
}

Výše uvedené mi poskytuje následující sloupce v pgAdmin :

2) Přidružení

Následující přidružení nedává smysl a mělo by způsobit chybu:

Leg.hasOne(Paw)
Paw.hasMany(Leg)

Unhandled rejection Error: Cyclic dependency found. Legs is dependent of itself.
Dependency chain: Legs -> Paws => Legs

Každá Leg by měl mít jednu Paw , a proto navrhuji následující:

Leg.associate = function (models) {
  // Leg.belongsTo(models.Cat)
  Leg.hasOne(models.Paw, {
    foreignKey: 'pawId',
    as: 'paw'
  })
}

Paw.associate = function (models) {
  Paw.belongsTo(models.Leg, {
    as: 'leg' // note this changed to make more sense
    foreignKey: 'pawId'
  })
}

3) Cizí klíče

Leg.belongsTo(models.Cat, {
  foreignKey: 'catId', // this should match
  onDelete: 'CASCADE'
})

Cat.hasMany(models.Leg, {
  foreignKey: 'catId', // this should match
  as: 'legs'
})

4) Dychtivé načítání

Když dychtivě načítáte vnořená přidružení, musíte include jim. Měli byste také použít as alias, který odpovídá vašim přidružením k modelu:

Cat.findAll({
  include: [{
    model: Leg,
    as: 'legs', // Cat.legs 
    include: [{
      model: Paw,
      as: 'paw' // Leg.paw instead of Leg.pawId
    }]
  }]
})

Pomocí celého tohoto nastavení a výše uvedeného dotazu získám:

[
  {
    "id": 1,
    "userId": "1",
    "createdAt": "2018-04-15T11:22:59.888Z",
    "updatedAt": "2018-04-15T11:22:59.888Z",
    "legs": [
      {
        "id": 1,
        "originalValue": null,
        "newValue": null,
        "objectId": null,
        "createdAt": "2018-04-15T11:22:59.901Z",
        "updatedAt": "2018-04-15T11:22:59.901Z",
        "catId": 1,
        "paw": {
          "id": 1,
          "pawType": null,
          "createdAt": "2018-04-15T11:22:59.906Z",
          "updatedAt": "2018-04-15T11:22:59.906Z",
          "pawId": 1
        }
      }
    ]
  }
]

Navíc

Protože se zjevně jedná o cvičné nastavení, můžete upravit Paw být belongsToMany vztah (možná máte spojené kočky za tlapu?) takto:

Paw.associate = function (models) {
  Paw.belongsToMany(models.Leg, {
    foreignKey: 'pawId',
    through: 'PawLegs  // a through join table MUST be defined
  })
}

Toto by byl správný způsob, jak implementovat to, o co jste se původně pokoušeli

Leg.hasOne(paw)
paw.hasMany(leg)



  1. Jak funguje funkce REGEXP_LIKE() v MySQL

  2. SQL dotaz pomocí klauzule WHERE IN

  3. Pokoušíte se refaktorovat rekurzivní dotaz v Oracle CTE?

  4. Formát data SQL