Mon modèle de base de données est le suivant:
Un employé conduit un ou zéro véhicule
Un véhicule peut être conduit par un ou plusieurs employés
Un véhicule a un type de modèle qui nous indique entre autres le type de carburant.
Je voudrais que me chercher tous les employés où ils ne conduisent pas de véhicule, ou s'ils le font, alors le véhicule n'est pas diesel.
Donc, VehicleID est nul OR Vehicle.VehicleModel.IsDiesel = false
Mon code actuel est le suivant:
var employee = sequelize.define('employee', {
ID: Sequelize.INTEGER,
VehicleID: Sequelize.INTEGER
});
var vehicle = sequelize.define('vehicle', {
ID: Sequelize.INTEGER,
ModelID: Sequelize.INTEGER
});
var vehicleModel = sequelize.define('vehicleModel', {
ID: Sequelize.INTEGER,
IsDiesel: Sequelize.BOOLEAN
});
employee.belongsTo(vehicle);
vehicle.belongsTo(vehicleModel);
Si je lance ce qui suit:
options.include = [{
model: model.Vehicle,
attributes: ['ID', 'ModelID'],
include: [
{
model: model.VehicleModel,
attributes: ['ID', 'IsDiesel']
}]
}];
employee
.findAll(options)
.success(function(results) {
// do stuff
});
Sequelize fait une jointure externe gauche pour obtenir les tables incluses. J'ai donc des employés qui conduisent des véhicules et qui ne le font pas.
Dès que j'ajoute un où à mes options:
options.include = [{
model: model.Vehicle,
attributes: ['ID', 'ModelID'],
include: [
{
model: model.VehicleModel,
attributes: ['ID', 'IsDiesel']
where: {
IsDiesel: false
}
}]
}];
Sequelize fait maintenant une jointure interne pour obtenir les tables incluses.
Cela signifie que je n'ai que des employés qui conduisent un véhicule et le véhicule n'est pas diesel. Les employés qui ne conduisent pas de véhicule sont exclus.
Fondamentalement, j'ai besoin d'un moyen de dire à Sequelize de faire une jointure externe gauche et en même temps d'avoir une condition where qui indique que la colonne de la table jointe est fausse ou nulle.
MODIFIER:
Il s'avère que la solution consistait à utiliser required: false, comme ci-dessous:
options.include = [{
model: model.Vehicle,
attributes: ['ID', 'ModelID'],
include: [
{
model: model.VehicleModel,
attributes: ['ID', 'IsDiesel']
where: {
IsDiesel: false
},
required: false
}],
required: false
}];
J'avais déjà essayé de mettre le premier "requis: faux" mais j'ai manqué de mettre celui intérieur. Je pensais que cela ne fonctionnait pas, alors j'ai abandonné cette approche. La réponse de Dajalmar Gutierrez m'a fait réaliser que j'avais besoin des deux pour que cela fonctionne.
Lorsque vous ajoutez une clause where, sequelize ajoute automatiquement une required: true
à votre code.
Ajout required: false
à votre segment d'inclusion devrait résoudre le problème
Remarque: vous devez vérifier ce problème iss4019
Chargement avide
Lorsque vous récupérez des données de la base de données, il y a de fortes chances que vous souhaitiez également obtenir les associations avec la même requête - cela s'appelle chargement avide . L'idée de base derrière cela est l'utilisation de l'attribut include lorsque vous appelez find ou findAll. lorsque vous définissez
requis: faux
ça ira
LEFT OUTER JOIN
quand
requis: vrai
ça ira
INNER JOIN
pour plus de détails docs.sequelizejs eager-loading