Я пытаюсь определить, проголосовал ли пользователь за question
. Пользователь нажимает кнопку «за» / «против», которая делает запрос к API, который извлекает их id
из формы ie и затем сохраняет ее в массиве upvoters
или downvoters
. Logi c с положительным / отрицательным голосом работает должным образом - проблем нет - однако у меня возникают проблемы с определением, содержит ли массив upvoters
или downvoters
их id
, когда пользователь запрашивает вопросы с помощью Speci c tag.
Модель вопроса:
Column │ Type │ Modifiers
─────────────────────────┼───────────────────────────┼──────────────────────────────────────────────
key │ Serial │ PRIMARY KEY
userid │ UUID │ NOT NULL REFERENCES users(id)
date │ TIMESTAMP │ WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
answered │ BOOLEAN │ DEFAULT FALSE
views │ INTEGER │ DEFAULT 0
upvoters | TEXT[] | DEFAULT array[]::text[]
downvoters | TEXT[] | DEFAULT array[]::text[]
title | TEXT | NOT NULL DEFAULT ''
uniquetitle | VARCHAR | NOT NULL DEFAULT ''
body | TEXT | NOT NULL DEFAULT ''
tags | TEXT[] | DEFAULT array[]::text[]
comments | JSONB |
Конечная точка API:
import get from "lodash.get";
import isEmpty from "lodash.isempty";
import db from "~db"; // connection to Postgres using pg-promise
const findAllQuestionsByTagLimitAndOffset = `
SELECT
questions.key,
questions.userid,
questions.date,
questions.body,
questions.answered,
questions.views,
cardinality(questions.upvoters)-cardinality(questions.downvoters) as votes,
EXISTS(
SELECT FROM questions WHERE questions.upvoters @> $4
) as upvoted, // check whether or not the logged in user has upvoted this question
EXISTS(
SELECT FROM questions WHERE questions.upvoters @> $4
) as downvoted, // check whether or not the logged in user has downvoted this question
questions.title,
questions.uniquetitle,
questions.tags,
users.username, // appends original poster's username
users.reputation as userrep, // appends original poster's rep
users.key as userkey // appends original poster's id
FROM questions
INNER JOIN users ON questions.userid=users.id
WHERE questions.tags @> $1
ORDER BY questions.date DESC
LIMIT $2
OFFSET $3
`;
/**
* Fetches questions by tag.
*
* @function fetchNewestQuestionsByTag
* @param {object} req - request object
* @param {object} res - response object
* @returns {array} data - questions that contain the queried tag with original poster populated data and some logged in user data
* @throws {string} err
*/
const fetchNewestQuestionsByTag = async (req, res) => {
try {
const { tag } = req.query;
if (!tag) throw String("Unable to locate questions because the tag is not valid.");
const userid = get(req.session, ["id"]);
const data = await db.any(findAllQuestionsByTagLimitAndOffset, [
[tag],
10,
0,
[userid],
]);
if (isEmpty(data)) throw String("Unable to locate any questions.");
res.status(201).send(data);
} catch (err) {
res.status(404).send(err);
}
};
Вот как question
выглядит после голосования за:
answered: false
body: "Test"
date: "2020-06-19T20:24:46.496Z"
downvoters: []
comments: []
title: "Test Title"
tags: ["reactjs"]
uniquetitle: "test-title"
upvoters ["d17a33f4-b26a-11ea-9372-131fa959a01b"] // logged in user id is stored
userid: "d17a33f4-b26a-11ea-9372-131fa959a018"
views: 1
После того, как пользователь проголосовал за и обновил страницу и / или запросил вопрос, за который он проголосовал с помощью тега, возвращается следующая (неверная) структура данных:
answered: false
body: "Test"
date: "2020-06-19T20:24:46.496Z"
downvoted: false
tags: ["reactjs"]
title: "Test Title"
uniquetitle: "test-title"
upvoted: false // this should be true as the logged in user is "d17a33f4-b26a-11ea-9372-131fa959a01b" and their id is contained within this array, yet it is still false
userid: "d17a33f4-b26a-11ea-9372-131fa959a018"
userkey: 1
username: "Matt"
userrep: 0
views: 1
votes: 1
Проблема состоит в том, что эти запросы всегда возвращают false:
EXISTS(
SELECT FROM questions WHERE questions.upvoters @> $4
) as upvoted,
EXISTS(
SELECT FROM questions WHERE questions.downvoters @> $4
) as downvoted,
Я пробовал следующее, и ни один из них не возвращает правильный логический статус:
Как сделать выбор с массивом, содержащим предложение значения в psql
Проверить, существует ли значение в Postgres массиве
Postgres: проверить, содержит ли поле массива значение?
Что я делаю не так?