2016-10-03 3 views
0

В настоящее время я работаю над приложением для управления филиалами и сотрудниками компании, используя NodeJS, MSSQL и Sequilize в качестве ORM.Sequelize: Включая атрибуты join table в findAll include

Требование состоит в том, чтобы отслеживать определенные изменения таким образом, чтобы мы могли «вернуться» к дате в прошлом и видеть состояние компании в этот конкретный момент времени. Для этого мы используем отметки времени (initDate и endDate) для отслеживания изменений, о которых мы заботимся, т. Е. Изменений в филиалах и перемещения сотрудников среди активных ветвей. Каждый раз, когда изменяется запись, мы устанавливаем ее endDate на now() и создаем новую запись с изменением и endDate = null, поэтому «текущая» версия каждой ветви или отношения ветви-сотрудника равна endDate IS NULL.

Проблема, которую мы сталкиваемся сейчас с Sequelize: Как мы можем указать endDate для отношения ветвей работника при findAll() ING наших сотрудников, в то время как нетерпеливый-налива (т.е. include ю) их филиалов? В приведенном ниже примере я запрашиваю текущее состояние компании, поэтому я прошу endDate: null, но на самом деле это аргумент, говорящий о времени, которое мы хотим.

Большое спасибо за помощь. Любое понимание было бы действительно оценено!

--- Здесь я включаю определение модели и запрос ---

Branch определение модели:

var BranchModel = db.define<BranchInstance, Branch>('Branch', { 
    IdBranch: { 
     primaryKey: true, 
     type: DataTypes.INTEGER 
    }, 
    Name: DataTypes.STRING, 
    // ... other fields ... 
    initDate: DataTypes.DATE, 
    endDate: DataTypes.DATE 
}, { 
    timestamps: false, 
    classMethods: { 
     associate: function (models) { 

      Branch.belongsToMany(models.model('Employee'), { 
       through: { 
        model: models.model('Branch_Employee') 
       }, 
       as: 'Employees', 
       foreignKey: 'branchId' 
      }); 

      // ... other associations .. 

     } 
    } 
}); 

модели Employee определение:

var EmployeeModel = db.define<EmployeeInstance, Employee>('Employee', { 
    idEmployee: { 
     primaryKey: true, 
     type: DataTypes.INTEGER 
    }, 
    Name: DataTypes.STRING, 
    // ... other fields ... 
    active: DataTypes.BOOLEAN 
}, { 
    timestamps: false, 
    defaultScope: { 
     where: { 
      active: true 
     } 
    }, 
    classMethods: { 
     associate: function (models) { 

      EmployeeModel.belongsToMany(models.model('Branch'), { 
       through: { 
        model: models.model('Branch_Employee') 
       }, 
       foreignKey: 'employeeId' 
      }); 

      // ... other associations ... 
     } 
    } 
}); 

Регистрацию определение таблицы:

var Branch_Employee = db.define<BranchEmployeeInstance, BranchEmployee>('Branch_Employee', { 
    branchId: DataTypes.INTEGER, 
    employeeId: DataTypes.INTEGER 
    // ... some other attributes of the relation ... 
    initDate: DataTypes.DATE, 
    endDate: DataTypes.DATE, 
}, { 
    timestamps: false, 
    classMethods: { 
     associate: function(models) { 

      Branch_Employee.belongsTo(models.model('Employee'), { 
       as: 'Employee', 
       foreignKey: 'employeeId' 
      }); 

      Branch_Employee.belongsTo(models.model('Branch'), { 
       as: 'Branch', 
       foreignKey: 'branchId' 
      }); 
     } 
    }, 
    instanceMethods: { 
     // ... some instance methods ... 
    } 
}); 

Sequelize запрос, чтобы получить каждый активный сотрудник, жаждущих загрузки филиалов, к которым они относятся:

let employees = await EmployeeModel.findAll({ 
    logging: true, 
    include: [{ 
     model: Branch, 
     as: 'Branches', 
     where: { 
      endDate: null, // this would be [Branches].[endDate] IS NULL 

      // i also need the generated query to include: 
      // [Branches.Branch_Employee].[endDate] IS NULL 

     }, 
     required: false 
    }] 
}); 

Сгенерированный SQL для приведенного выше запроса, выглядит следующим образом:

SELECT [Employee].[idEmployee] 
,[Employee].[Name] 
,[Employee].[active] 
,[Branches].[IdBranch] AS [Branches.IdBranch] 
,[Branches].[Name] AS [Branches.Name] 
,[Branches].[initDate] AS [Branches.initDate] 
,[Branches].[endDate] AS [Branches.endDate] 
,[Branches.Branch_Employee].[initDate] AS Branches.Branch_Employee.initDate] 
,[Branches.Branch_Employee].[endDate] AS [Branches.Branch_Employee.endDate] 
,[Branches.Branch_Employee].[branchId] AS Branches.Branch_Employee.branchId] 
,[Branches.Branch_Employee].[employeeId] AS [Branches.Branch_Employee.employeeId] 
FROM [Employee] AS [Employee] 
LEFT OUTER JOIN (
    [Branch_Employee] AS [Branches.Branch_Employee] 
    INNER JOIN [Branch] AS [Branches] 
    ON [Branches].[IdBranch] = [Branches.Branch_Employee].[branchId] 
) ON [Employee].[idEmployee] = [Branches.Branch_Employee].[employeeId] 
AND [Branches].[endDate] IS NULL 
WHERE [Employee].[active] = 1; 

Но я на самом деле необходимо дополнительно ограничить результирующий набор включают только «текущие» Branch-трудовые отношения, то есть что-то вроде:

[Branches.Branch_Employee].[endDate] IS NULL 

ответ

0

я должен был дать больше кредита я e Sequelize docs, поскольку, как это часто бывает, у него был ответ. Я включил его в случае, если кто-то борется с этой конкретной проблемы:

Из Sequelize doc, функция findAll(options) принимает следующий вариант:

[options.include[].through.where] Фильтр объектов на вступление модели отношений belongsToMany.

Это именно то, что мне нужно! Надеюсь это поможет.

Смежные вопросы