2017-02-13 9 views
0

У меня есть уже существующие таблицы в SQL Server, и я хочу использовать эти таблицы в проекте NodeJs.Ассоциации SequelizeJs в NodeJs для MsSql

Первая таблица представляет собой таблицу отчетов и имеет столбцы {ReportId, ReportName}.

Вторая таблица - таблица «Избранное», в ней есть столбцы {FavouriteId, ReportId, UserName}.

Вы можете найти ниже. Я хотел бы назначить внешние ключи и сделать зависимость. В конце я хочу выбрать отчеты с любимым флагом для конкретного пользователя.

module.exports = function(sequelize, DataTypes) { 
    var Favourite = sequelize.define("IUI_Favourites", { 
      favourite_id: { 
       type: DataTypes.INTEGER, 
       primaryKey: true, 
       field: 'iui_favourite_id' 
      }, 
      report_id: { 
       type: DataTypes.INTEGER, 
       field: 'iui_report_id' 
      }, 
      username: { 
       type: DataTypes.STRING, 
       field: 'iui_username' 
      } 
     }, 
     { 
      timestamps: false, 
      freezeTableName: true 
     }); 
    return Favourite; 
}; 


module.exports = function(sequelize, DataTypes) { 
    var Report = sequelize.define("IUI_Reports", { 
     report_id: { 
      type: DataTypes.INTEGER, 
      primaryKey: true, 
      field: 'iui_report_id' 
     }, 
     report_name: { 
      type: DataTypes.STRING, 
      field: 'iui_report_name' 
     } 
    }, 
    { 
     timestamps: false, 
     freezeTableName: true 
    }); 
    return Report; 
}; 

Помогите мне? Спасибо заранее.

ответ

3

В модели Favourite вам нужно создать объект недвижимости classMethods с помощью функции associate.

// in Favourite model 
    classMethods: { 
     associate: function(models){ 
      this.belongsTo(models.Report, { foreignKey: 'iui_report_id' }); 
     } 
    }, 
    timestamps: false, 
    freezeTableName: true 
}); 

Это определяет, что модель Favourite может иметь Report назначена через iui_report_id ссылочного поля в базе данных.

Затем в Report модели вы должны определить 1: M отношения:

// in Report model 
    classMethods: { 
     associate: function(models){ 
      this.hasMany(models.Favourite, { foreignKey: 'iui_report_id' }); 
     } 
    }, 
    timestamps: false, 
    freezeTableName: true 
}); 

Чтобы вернуть отчеты, которые Добавлен в избранное по заданному пользователем, вы должны вызвать метод findAll() на Report с определенными условиями:

Report.findAll({ 
    include: [ 
     { 
      model: Favourite, 
      where: { 
       username: 'admin' 
      } 
     } 
    ] 
}).then((reports) => { 
    // here you get reports that are favourited by user with username 'admin' 
}); 

Это будет генерировать SQL запрос, который будет возвращать как Report и Favourite объектов с использованием JOIN состояние на reports.id = favourite.report_id и favourite.username = 'admin'. Я надеюсь, что это то, что вы ищете.

EDIT

Согласно комментариям, вы хотите установить любимый флаг true, если указанный отчет Добавлен в избранное любым пользователем. Для этого вам нужно добавить это поле флага в модель Report, что-то вроде is_favourited. Это может быть поле, хранящееся в базе данных, или поле virtual sequelize с собственным getter (виртуальные поля не хранятся в базе данных).

В случае виртуального поля он может выглядеть так:

var Report = sequelize.define('report', { 
    ... 
    is_favourited: { 
     type: DataTypes.VIRTUAL(DataTypes.BOOLEAN), 
     get: function() { 
      return sequelize.models.Favourite.count({ 
       where: { iui_report_id: this.get('report_id') } 
      }).then((countResult) => { 
       return countResult > 0; 
      }); 
     } 
    } 
}, { 
    // additional model options e.g. classMethods etc. 
}); 

Этот виртуальный атрибут возвращает true если есть Favourite объекта с указанным iui_report_id значения. Однако, это асинхронное, так что вы должны назвать его .then() как report.get('is_favourited').then((result) => { console.log(result); });

С другой стороны, если вы хотите сохранить этот флаг в базе данных, вам придется вручную установить значение is_favourited поля истину при создании нового Favourite модель экземпляров. Для этого вы можете использовать крючок afterCreate на модели Favourite.

// in Favourite model 
timestamps: false, 
freezeTableName: true, 
hooks: { 
    afterCreate: function(instance, options) { 
     return sequelize.models.Report.findById(instance.get('iui_report_id').then((report) => { 
      if (company && !company.get('is_favourited')) { 
       return company.set('is_favourited', true).save().then(() => { return; }); 
      } 
    } 
} 

// in Report model 
var Report = sequelize.define('report', { 
    ... 
    is_favourited: { 
     type: DataTypes.BOOLEAN, 
     defaultValue: false 
    } 
}, { 
    // other model options... 
}); 

EDIT 2

Согласно последней комментарий Вы хотите создать запрос, как этот

SELECT Reps.rep_id, Reps.rep_name, CASE WHEN Favs.rep_id IS NULL THEN FALSE ELSE TRUE END is_favourited 
FROM Reps 
LEFT OUTER JOIN (SELECT rep_id FROM Favs WHERE user = 'alex') Favs ON Reps.rep_id = Favs.rep_id 

Этот запрос всегда будет возвращать is_favourited = TRUE, потому что ваш ON условие в JOIN статья Reps.rep_id = Favs.rep_id, поэтому даже если Favs.rep_id является NULL, то условие ON не будет проходить (поскольку Reps.rep_id является первичным ключом и не может быть NULL).

Однако, если вы действительно хотите, чтобы выполнить такой запрос, он будет выглядеть следующим образом

Report.findAll({ 
    include: [ 
     { 
      model: Favourite, 
      where: { username: 'alex' }, // or any other passed value 
      attributes: [] 
     } 
    ], 
    attributes: ['report_id', 'report_name', sequelize.literal('CASE WHEN "IUI_Favourites"."report_id" IS NULL THEN FALSE ELSE TRUE END is_favourited')], 
    raw: true // because your Report model does not have is_favourited field 
}).then((rows) => { 
    // result 
}); 
+0

Великий ответ спасибо. Последнее, что я хочу получить все отчеты с любимым флагом. Это означает, что если один пользователь уведомляется администратором, флаг должен быть true, иначе false. Как это возможно? И когда я выбираю таблицы, любимая таблица имеет множественное число. Как я могу получить это единственное число? –

+0

Я не совсем понимаю часть с любимым флагом. Вы имеете в виду, что если конкретный отчет был предоставлен ЛЮБОЙ пользователь, у него должен быть установлен флажок для избранного? Если дело доходит до любимой таблицы, она приходит во множественном числе из-за того, что это отношение 1: M, поэтому объект Report Report поставляется со многими объектами Favourite. – piotrbienias

+0

Извините за недоразумение, любимый флаг - это первый вопрос. Вторая часть - второй вопрос. Флаг избранного - важная часть. И да, вы правы, если какой-либо отчет был одобрен любым пользователем, он должен иметь флаг избранного, установленный в true, иначе false. Если вы поможете, я буду признателен. Благодарю. –