Помощь

Discourse, создание своих наград

discourse
ruby
программирование

(Евгений) #1

Запросы (sql) для наград в Discourse не представляются администраторам, по умолчанию.

Это было сделано по нескольким причинам:

  • Безопасность: позволить администраторам вводить SQL напрямую это понизить общую линию безопасности. Даже администратору вовсе не обязательно иметь прямой доступ к базе данных.

  • Производительность: получение значка SQL «just right» - это искусство, для адмистраторов это не то, что они должны уметь делать правильно. Существует огромный риск того, что люди, которые не являются экспертами, могут создавать огромную нагрузку на базу данных, введя плохой SQL запрос.

Тем не менее, мы можем получить полный авторский доступ, выполнив:

./launcher enter app
rails c
> SiteSetting.enable_badge_sql = true

в командной строке.

SiteSetting.enable_badge_sql = false (по умолчанию). Вам следует вернуть это значение после проведение работ.

Ниже приведены запросы, которые необходимо вставить во вновь появившиеся окно:

Значок для первого принятого ответа:

SELECT p.user_id, p.id post_id, p.updated_at granted_at
FROM badge_posts p
WHERE p.post_number > 1 AND 
    p.id IN (
      SELECT post_id FROM (
       SELECT pc.post_id, row_number() 
       OVER (PARTITION BY p1.user_id ORDER BY pc.created_at) as rnum
       FROM post_custom_fields pc
       JOIN badge_posts p1 ON p1.id = pc.post_id
       JOIN topics t1 ON p1.topic_id = t1.id
       WHERE name = 'is_accepted_answer' AND
                    p1.user_id <> t1.user_id AND 
        (
          :backfill OR 
           p1.user_id IN (
                   select user_id from posts where p1.id IN (:post_ids)
           )
       )
) X  WHERE rnum = 1)

Если вы хотите сделать еще одну награду, то создайте её используя следующий запрос:

Значок для 10 принятых ответов:

SELECT id user_id, current_timestamp granted_at
FROM users
WHERE id  IN (
       SELECT p1.user_id 
       FROM post_custom_fields pc
       JOIN badge_posts p1 ON p1.id = pc.post_id
       JOIN topics t1 ON p1.topic_id = t1.id
       WHERE p1.user_id <> t1.user_id AND 
                    name = 'is_accepted_answer' AND 
                    value IS NOT NULL AND
            p1.user_id IN (
                   SELECT user_id 
                   FROM posts 
                   WHERE :backfill OR  p1.id IN (:post_ids)
            )
        GROUP BY p1.user_id
        HAVING COUNT(*) > 9
)

Посмотрите новые награды в разделе награды, и убедитесь в том, что они присваиваются.

Отдельно необходимо обратить внимание, как вы поставили пересчет (раз в сутки, после обработки сообщения и т.д.). Эти функции находятся на странице добавления награды (сразу под окном с SQL запросом).


(Petrenko) #2

Выдать награду, если пользователь создал хотя бы один вопрос в разделе “comm”

SELECT p.user_id, min(p.created_at) granted_at, MIN(p.id) post_id
FROM badge_posts p
JOIN topics t ON t.id = p.topic_id
WHERE category_id = (
  SELECT id FROM categories WHERE name ilike 'comm'
) AND p.post_number = 1
GROUP BY p.user_id

Выдать награду, если пользователь создал 5 вопросов в разделе “comm”

SELECT p.user_id, min(p.created_at) granted_at, MIN(p.id) post_id
FROM badge_posts p
JOIN topics t ON t.id = p.topic_id
WHERE category_id = (
  SELECT id FROM categories WHERE name ilike 'comm'
) AND p.post_number = 1
GROUP BY p.user_id
HAVING count(*) > 4

Выдать награду, всем участникам группы “comm”

SELECT user_id, created_at granted_at, NULL post_id
FROM group_users
WHERE group_id = (
  SELECT g.id FROM groups g WHERE g.name = 'coom'
)