170 похожих чатов

Всем привет! В БД есть 3 таблицы - article, article_tag, article_tag_many

(многие-ко-многим). При попытке вручную добавить сначала новую article, потом несколько article_tag, а затем их id в article_tag_many - всё ок, с базой проблем нет.

Использую Knex.js + Bookshelf.js. На вход метода add (article) одним из параметров попадает tags - это масив объектов вида [{tag: "тег1"}, {tag: "тег2"}, {tag: "тег3"}]. Далее создается article. Следующим шагом - article_tags. И теперь мне необходимо сохранить в article_tag_many значения id передаваемых в метод тегов.

Т.e. теги в таблицу с тегами записались, как теперь средствами ORM получить их id , чтобы записать в article_tag_many?

Пробовал такое: const tagId = await knex.raw(`select nextval('article_tag_id_seq')`);
И далее - Number(tagId.rows[0]['nextval']) - idOffset как значение id тега (где idOffset - количество объектов в передаваемом массиве)

Но такой подход мне не нравится + к тому же он еще и не работает: в консоли я вижу правильные значения идентификаторов (в базе ровно такие же значения после вызова метода):

ArticleId 197
TagId 415
ArticleId 197
TagId 416
ArticleId 197
TagId 417

Но в итоге появляется ошибка:

UnhandledPromiseRejectionWarning: error: insert or update on table "article_tag_many" violates foreign key constraint "article_tag_many_tag_id_fkey"

Вот код:

export async function add(<SomeAttrs here>, tags, <SomeAttrs here>) {
try {
const myArticle = new Article({ <SomeAttrs here> });

await myArticle.save();

for (const tag of tags) {
await new Tags({ tag: tag['tag'] }).save();
}

const articleId = await knex.raw(`select nextval('article_id_seq')`);

tags.forEach(async (_tag) => {
const tagId = await knex.raw(`select nextval('article_tag_id_seq')`);

try {
await myArticle.related('tags').create({
articleId: Number(articleId.rows[0]['nextval']) - 1,
tagId: Number(tagId.rows[0]['nextval']) - 3
});
} catch (err) {
throw err;
}
});

return myArticle;
} catch (error) {
throw new BadRequestError(error.message);
}
}

5 ответов

17 просмотров
Aleksei-V. Автор вопроса

Оно не работает ни с for ... of, ни с for await ... of, более того, в методе add есть еще такая логика (sections - массив чисел, тоже связь там many-to-many), эта часть кода работает: sections.forEach(async section => { try { await myArticle.related('section').create({ sectionId: section }); } catch (err) { throw err; } });

работать-то она работает, но forEach не ждет await.

Aleksei-V. Автор вопроса

В общем, мой метод не работал, потому что я неправильно прописал логику в моделях, теперь всё работает. По поводу 'не ждёт await' - а как правильно? Вот так? for await (const section of sections) { await myArticle.related('section').create({ sectionId: section }); }

без for await, просто for или через await Promise.all

Aleksei-V. Автор вопроса

Понятно, благодарю!

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
Карта сайта