Вставить в таблицу отношений "один ко многим" с помощью sequelize с существующим внешним ключом - PullRequest
0 голосов
/ 09 июля 2020

У меня следующие модели:

Sports.init({
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: false
        }
    }, {sequelize, tableName: 'sports'});
    
Leagues.init({
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: false
        }
    }, {sequelize, tableName: 'leagues'});

Связь между ними следующая.

Sports.Leagues = Sports.hasMany(Leagues, {foreignKey: {name: "sports_id", allowNull: false}, sourceKey: "id"});
Leagues.Sports = Leagues.belongsTo(Sports, {foreignKey: {name: "sports_id", allowNull: false}, targetKey: "id"});

У меня уже есть запись в таблице Sports: {name: "Basketball", id: 1} I хотите создать запись в таблице Лиги, ссылающуюся на уже существующую спортивную запись. Как я могу сделать это с помощью одной функции? Я просмотрел документацию, но ничего подходящего там не нашел. Я знаю, что смогу сделать это следующим образом, если запись, на которую я ссылаюсь, не существует:

await Leagues.create({name: leagueName, espn_name: espnName, Sport: {name: "Basketball"}}, {include: Leagues.Sports});

Однако я не нашел ничего о том, как это сделать , если внешний ключ уже существует, кроме ручного выполнения чего-то вроде этого:

await Sports.findOne({where: {name: sportName}}).then((res) => {
        if(res) {
            return Leagues.create({name: leagueName, espn_name: espnName, sports_id: res.get("id")});
        }
    });

Мне кажется, что это слишком много кода для относительно простой операции. Есть ли способ сделать это «умнее» или короче? Заранее спасибо!

1 Ответ

0 голосов
/ 10 июля 2020

Я нашел аналогичный вопрос по stackoverflow. Таким образом, похоже, что нет другого способа сделать это, кроме как вручную найти идентификатор, а затем прикрепить его непосредственно к новой записи. Однако я сделал ярлык, чтобы легче обрабатывать такие запросы. Итак, я создал новый класс, который расширился из класса модели sequelize и добавил новую функцию stati c, которая сама по себе обрабатывает выборку идентификатора:

export class CustomModel extends Model {
    static async getId<M extends Model>(attributes: M['_creationAttributes']) {
        const res = await this.findOne({where: attributes});
        if(!res) {
            throw new Error(`Can not find id of the record in the table ${this.tableName}`);
        }
        return res.get("id")
    }
}

И мои модели теперь расширяются из этого класса:

export class Sports extends CustomModel{
    static Leagues: HasMany<Sports, Leagues>;
}

Sports.init({
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: false
        }
    }, {sequelize, tableName: 'sports'});

Итак, теперь можно добавлять новые записи с уже существующим ключом с меньшим кодом:

 await Leagues.create({name: "u", sports_id: await Sports.getId({name: "Basketball"})});
...