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 ответов

7 просмотров
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. Автор вопроса

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

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

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

Типа вызывать GetParent и проверять на соответствие GetModuleHandle?
The Bird of Hermes
67
Do any of you guys have interesting projects one could join? I'm a Middle Full-Stack developer (JS/TS, React & Node)
Lev Shapiro
40
$res = json_decode($наша строка из респонса); $res1 = array_map(fn($o) => $o->name, $res->breadcrumbs[0]->entities); Как такое будет на Хаскеле?.. В начале весь джейсон, в ко...
Хаскель Моисеевич Гопник
24
В чем сила брат, в NASM или FASM?
Isaac Kleiner
18
Вопрос по диагностике ошибок (я знаю в чем, в данном конкретном примере, я знаю, как исправить, пример модельный, понятно, что в реальности бывает намного запутаннее). module...
ⰄⰎⰋⰐⰐⰑⰛⰤⰧⰧⰩⰄ ⰊⰑⰁⰓⰡⰛⰦⰕⰫ
10
Хтось використовував Vapor на Windows?
Jaroshevskii
15
Тут кста кто-нибудь NeoVim использует?
Simple Sorcerer
13
А чем вам питонисты не угодили?😂
.
79
Есть какой-нибудь для Delphi/FPC T*Compression(Decompression)Stream на базе LZ4/Zstd/любой другой быстрый(и хорошо сжимающий) алгоритм А ещё лучше в pure pascal А ещё лучше од...
notme
52
у меня вопрос на счет .global <name> для чего это нужно если я пишу на ассемблере? только для того что бы сделать это видимым для линкера? вот что написано в докумментации GA...
Simple Sorcerer
1
Карта сайта