Заполните данные без идентификатора ассоциации в Sequelize - PullRequest
0 голосов
/ 20 марта 2019

У меня есть 4 таблицы: пользователь, профиль, специальность, user_specialities.Я использую sequelize.Моя модель пользователя ->

const User = sequelize.define('user', {
user_id: {
        type: Sequelize.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true,
    },
    IsDeleted: {
        type:Sequelize.BOOLEAN,
    },
    status: {
        type:Sequelize.BOOLEAN,
},
});

Модель моих профилей ->

const Profile= sequelize.define('profile', {
    profile_id: {
        type: Sequelize.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true,
    },
    first_name: {
        type:Sequelize.STRING,
    },
    last_name: {
        type:Sequelize.STRING,
    },
},
{
    indexes: [
        {
            unique: true,
            fields: ['user_id']
        }
    ]
});   
Chef_Info.belongsTo(User, {foreignKey: 'user_id'});

Таблица специальности ->

    const Profile= sequelize.define('speciality', {
        speciality_id: {
            type: Sequelize.INTEGER,
            allowNull: false,
            primaryKey: true,
            autoIncrement: true,
        },
        title: {
            type:Sequelize.STRING,
        },
}

user_specialities содержит многомного отношений между пользователем и специальностью.Я использовал belongsToMany ассоциацию, подобную этой -

Speciality.belongsToMany(User, {through: 'user_speciality',foreignKey: 'speciality_id', otherKey: 'user_id'});
User.belongsToMany(Speciality, {through: 'user_speciality',foreignKey: 'user_id', otherKey: 'speciality_id'});

Теперь я хочу получить данные, где у меня есть user_id, first_name, last_name и особенности.Например ->

first_name  | last_name     | specialities
Khabib      | Nurmagamedov  | Athlete, Wrestler
Tony        | Ferguson      | Athlete, Striker

Я пробовал в MySql, где запрос должен быть ->

SELECT profiles.first_name,profiles.last_name,GROUP_CONCAT(specialities.title)
FROM (
users
    LEFT JOIN profiles
         ON users.user_id = profiles.user_id 
    LEFT JOIN user_specialities
        ON users.user_id = user_specialities.user_id
    LEFT JOIN specialities
        ON chef_specialities.speciality_id = specialities.speciality_id
)
WHERE(
    AND users.IsDeleted = false
    And users.status = true
)
GROUP BY users.user_id;

Но я изо всех сил пытаюсь преобразовать это в секвелиз.Я зашел так далеко ->

UserSpecialities.findAll({
    attributes:[sequelize.fn('GROUP_CONCAT', sequelize.col('title')), 'speciality_id'],
    include: [
    { 
       model: User,
       attributes: [],
       where:{
           IsRemoved: false,
           status: true,
       },
    },
    { model: Speciality,
         attributes: [],
    },
    ],
    group:['user_id']

Это обеспечивает специальность пользователя ->

[
    {
        "speciality_id": "Athlete, Wrestler",
    },
    {
        "speciality_id": "Athlete, Striker",
    }
]

Но я не могу заполнить данные профиля здесь. Если я пытаюсь включитьпрофиль, он не показывает ошибку ассоциации, или я пытаюсь добавить hasMany в модель пользователя, он снова выдает ошибку.Что мне делать в этой ситуации?Заранее спасибо.

1 Ответ

1 голос
/ 20 марта 2019

Поскольку профиль связан с пользователями, а не с пользовательскими специальностями, было бы разумнее выполнить это с помощью двух запросов.

Получите ваши пользовательские особенности, как вы делали выше, затем возьмите эти userId и захватите их связанные профили (должно быть что-то вроде User.getProfile в зависимости от того, как настроены ваши ассоциации).

Прямо сейчас у вас есть свои атрибуты UserSpecialties, настроенные так, чтобы они возвращали только specialty_id и title, если вы добавите userId к этим атрибутам, вы можете использовать эти userId для запроса таблицы вашего профиля.Обещание затем хорошо работает для чего-то подобного, например:

UserSpecialties.findAll({...}).then((userSpecialties) => {
  User.getProfile({where: {userId: userSpecialties.userId}, attributes: {'first_name', 'last_name'})
});

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

Хотя, глядя на ваши модели, возможно, имеет смысл просто иметь профильи пользователь будет одной таблицей, где пользователь имеет имя, фамилию, идентификатор пользователя и статус.Поскольку в Профиле нет много других вещей, а затем, если вам нужны определенные вещи для userProfile, вы можете использовать области действия в вашей пользовательской модели.

...