Vagner Wentz
Vagner Wentz

Reputation: 566

Sequelize - Trouble with includes association

What is happening?

I have a vehicle/announce route that returns all vehicles from the application, I have cars, motorcycles, agricultural machines, and agricultural implements. My problem is when it comes to returning data from agricultural machines and agricultural implements.

Sequelize Query

Annoucement.findAll({
        include: [{
            model: AnnoucementVehicle,
            include: [{
                model: Itens,
                include: [{
                    model: AgriculturalMachine,
                }],
                include: [{
                    model: Vehicle,
                    include: [{
                        model: OptionalHasVehicles,
                        // as: 'Optionals',
                        include: [{
                            model: Optional,
                        }]
                    }, {
                        model: VehicleHasFeatures,
                        include: [{
                            model: Features,
                        }],
                        // as: 'Optionals',
                    }, {
                        model: Fipe,
                        include: [{
                            model: Fuel,
                        }]
                    }]
                }],

            }, {
                model: VehicleImages
            }, {
                model: Person
            }]
        }],
        order: [
            ['id', 'DESC']
        ],
    }).then((result) => {
        return res.json({ success: true, result: result })
    }).catch((err) => {
        return res.status(400).json(err)
    });

JSON with an announcement car

{
  "success": true,
  "result": [
    {
      "id": 311,
      "active": true,
      "announcement_vehicle": {
        "idAnnouncementVehicles": 311,
        "price": null,
        "video": null,
        "description": null,
        "personId": 1,
        "itemId": 297,
        "payed": false,
        "plans_id": null,
        "createdAt": "2020-05-20T19:05:18.000Z",
        "updatedAt": "2020-05-20T19:05:18.000Z",
        "iten": {
          "id": 297,
          "type": "1",
          "vehicle": {
            "item_id": 297,
            "mileage": null,
            "license": null,
            "new": 0,
            "armoured": 0,
            "fuel_id": 1,
            "cambium_id": 1,
            "color_id": 1,
            "door_id": 1,
            "fipe_id": 1,
            "createdAt": "2020-05-20T19:05:18.000Z",
            "updatedAt": "2020-05-20T19:05:18.000Z",
            "optional_has_vehicles": [
              {
                ...
              }
            ],
            "vehicles_has_features": [
              {
                ...
                "feature": {
                  ...
                }
              },
            ],
            "fipe": {
              ....
              "fuel": {
                "id": 2,
                "description": "Gasolina"
              }
            }
          }
        },
        "announcemment_photos": [],
        "person": {
          ...
        }
      }
    },

But when it is an agricultural implement or agricultural machine, it returns me to where the vehicle arrives and shows how vehicle: null.

What have I tried?

I tried to put below at association: AnnouncementVehicle.associations.iten something like include: [{ association: AnnouncementVehicle.associations.agricultural_machine }]. Returns me the same JSON that I put above

What did I notice?

I realized that it always returns the last association, maybe something that I'm trying to do two include for two tables starting from the same. I put the association of agricultural machines well after the association of vehicles, and returned agricultural_machine: null and not returned vehicles.

Agricultural Machine Model

module.exports = function (sequelize, DataTypes) {
  const agricultural_machine = sequelize.define('agricultural_machine', {
    agricultural_machine_id: {
      type: DataTypes.INTEGER(11).UNSIGNED.ZEROFILL,
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'itens',
        key: 'id'
      },
      references: {
        model: 'agricultural_implement',
        key: 'agricultural_implement_id'
      },
      references: {
        model: 'tractor',
        key: 'tractor_id'
      }
    },
    worked_hours: {
      type: DataTypes.STRING(45),
      allowNull: true
    },
    year: {
      type: DataTypes.INTEGER,
      allowNull: false
    },
    description: {
      type: DataTypes.TEXT,
      allowNull: true
    },
    brand_agricultural_machine_id: {
      type: DataTypes.INTEGER(5).UNSIGNED.ZEROFILL,
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'brand_agricultural_machine',
        key: 'id'
      }
    },
    model_agricultural_machine_id: {
      type: DataTypes.INTEGER,
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'model_agricultural_machine',
        key: 'id'
      }
    }
  }, {
    tableName: 'agricultural_machine',
    timestamps: false
  });

  agricultural_machine.associate = (models) => {
    agricultural_machine.hasOne(models.tractor, { foreignKey: 'tractor_id' });
    agricultural_machine.hasOne(models.agricultural_implement, { foreignKey: 'agricultural_implement_id' });
    agricultural_machine.belongsTo(models.itens, { foreignKey: 'agricultural_machine_id' });
    agricultural_machine.belongsTo(models.brand_agricultural_machine, { foreignKey: 'brand_agricultural_machine_id' });
    agricultural_machine.belongsTo(models.model_agricultural_machine, { foreignKey: 'model_agricultural_machine_id' });
    //announcement_vehicles.belongsTo(models.persons,{foreignKey: 'personId'});
    //announcement_vehicles.hasMany(models.announcemment_photos,{foreignKey: 'annoucements_id', constraints: false});
  };

  return agricultural_machine;
};

Itens Model

module.exports = function (sequelize, DataTypes) {
  const itens = sequelize.define('itens', {
    id: {
      type: DataTypes.INTEGER(11).UNSIGNED.ZEROFILL,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    type: {
      type: "SET('1','2','3','4')",
      allowNull: false,
      defaultValue: '1'
    }
  }, {
    tableName: 'itens',
    timestamps: false
  });
  itens.associate = (models) => {
    itens.hasOne(models.vehicles, { foreignKey: 'item_id' });
    itens.hasOne(models.agricultural_machine, { foreignKey: 'agricultural_machine_id' });
  }

  return itens
};

Announcement Vehicle Model

module.exports = function (sequelize, DataTypes) {
  const announcement_vehicles = sequelize.define('announcement_vehicles', {
    idAnnouncementVehicles: {
      type: DataTypes.INTEGER(11).UNSIGNED.ZEROFILL,
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'annoucements',
        key: 'id'
      }
    },
    price: {
      type: DataTypes.DECIMAL,
      allowNull: true
    },
    video: {
      type: DataTypes.STRING(45),
      allowNull: true
    },
    description: {
      type: DataTypes.TEXT,
      allowNull: true
    },
    personId: {
      type: DataTypes.INTEGER(11).UNSIGNED.ZEROFILL,
      allowNull: true,
      references: {
        model: 'persons',
        key: 'id'
      }
    },
    itemId: {
      type: DataTypes.INTEGER(11).UNSIGNED.ZEROFILL,
      allowNull: true,
      references: {
        model: 'itens',
        key: 'id'
      }
    },
    payed: {
      type: DataTypes.BOOLEAN,
      allowNull: true
    },
    plans_id: {
      type: DataTypes.INTEGER(11).UNSIGNED.ZEROFILL,
      allowNull: true
    },
    createdAt: {
      type: DataTypes.DATE,
      allowNull: true
    },
    updatedAt: {
      type: DataTypes.DATE,
      allowNull: true
    }
  }, {
    tableName: 'announcement_vehicles'
  });

  announcement_vehicles.associate = (models) => {
    announcement_vehicles.belongsTo(models.itens, { foreignKey: 'itemId', constraints: false });
    announcement_vehicles.belongsTo(models.persons, { foreignKey: 'personId' });
    announcement_vehicles.hasMany(models.announcemment_photos, { foreignKey: 'annoucements_id', constraints: false });
  }

  return announcement_vehicles
};

Announcement Model

module.exports = function(sequelize, DataTypes) {
  var annoucements = sequelize.define('annoucements', {
    id: {
      type: DataTypes.INTEGER(11).UNSIGNED.ZEROFILL,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    active: {
      type: DataTypes.BOOLEAN
    } 
  }, {
    tableName: 'annoucements',
    timestamps: false
  });
  annoucements.associate = (models) => {
    annoucements.hasOne(models.announcement_vehicles,{foreignKey: 'idAnnouncementVehicles', constraints: false});
  }
  return annoucements
};

JSON that I receive when it's Agricultural Machine or Agricultural Implements

 {
      "id": 306,
      "active": true,
      "announcement_vehicle": {
        "idAnnouncementVehicles": 306,
        "price": "500.000,00",
        "video": null,
        "description": "TESTE TIPO 4",
        "personId": 1,
        "itemId": 292,
        "payed": false,
        "plans_id": null,
        "createdAt": "2020-05-18T23:57:18.000Z",
        "updatedAt": "2020-05-18T23:57:18.000Z",
        "iten": {
          "id": 292,
          "type": "4",
          "vehicle": null
        },
        "announcemment_photos": [],
        "person": {
          "id": 1,
          "email": "[email protected]",
          "password": "$2b$10$3OZVFYWeXKWLfxBMWJBYqua0qJPQkLl3sVgIFvZFuo6qBKj62dMQS",
          "name": "teste",
          "type": "fis",
          "createdAt": "2020-05-14T00:12:59.000Z",
          "updatedAt": "2020-05-14T00:12:59.000Z"
        }
      }
    },

The Diagram with the models mentioned

enter image description here

Upvotes: 1

Views: 95

Answers (1)

Anatoly
Anatoly

Reputation: 22813

All includes should look like:


 include: [{
        model: AnnoucementVehicle,
        as: 'Alias' // optional if you didn't indicate this alias in an association definition

In case of Itens includes it must be:

model: Itens,
  include: [{
    model: AgriculturalMachine,
  }, {
    model: Vehicle,
    include: [{
    ... // other includes
  }, {
    model: AgriculturalImplements,
  }, {
    model: Vehicle,
    include: [{
    ... // other includes

Upvotes: 1

Related Questions