Criamos um distintivo de bronze, Users Helping Users, para pessoas que tentam ajudar outros usuários. Ele é concedido manualmente (para que se possa diferenciar as tentativas de ser prestativo dos “eu também”).
Para cada 5 distintivos de bronze, queremos conceder um distintivo de prata, Invaluable.
O SQL que criei encontra os dois usuários certos, mas apenas uma vez cada:
SELECT user_id, current_timestamp AS granted_at
FROM user_badges
WHERE badge_id = 110 -- Users Helping Users
AND (:backfill OR user_id IN (:user_ids))
GROUP BY user_id
HAVING COUNT(*) >= 5
Estou perdendo alguma mágica no meu SQL, ou o multiplicador acontece fora do SQL?
Além disso, não está nada claro para mim como a matemática funciona para que meus dois usuários não recebam novos distintivos todos os dias (isso será executado em um gatilho noturno), mesmo que eles não tenham recebido 5 novos distintivos de bronze.
Existe um guia para isso que minha pesquisa não encontrou?
Ok, pesquisas mais aprofundadas me levaram a um rastro que me deixou em o guia
A coisa do backfill ainda é um pouco nebulosa, mas decidi (óbvio!) experimentar isso em nossa instância de teste. Suponho que o backfill seja executado durante a noite, então saberei mais amanhã.
A menos que você marque ‘Pode ser concedido várias vezes’, ele não deve ser concedido mais de uma vez, mesmo que eles se qualifiquem para ele uma segunda (ou mais) vez.
Ok, eu reli sua postagem com mais atenção e acho que tenho uma ideia mais clara do que você está buscando.
Com base no SQL atual, esses usuários só receberão a insígnia de prata uma vez, mesmo que você permita que ela seja concedida várias vezes:
Criei as insígnias relevantes em meu site de teste (incluindo permitir várias)
Concedi 5 de bronze e executei o trabalho em segundo plano para conceder a insígnia (insígnia de prata concedida com sucesso )
Então executei o trabalho BadgeGrant novamente e eles não receberam a prata uma segunda vez
Então aumentei suas insígnias de bronze para 11 e executei o trabalho de concessão de insígnias novamente
Essa é uma boa pergunta para a qual não sei a resposta imediatamente.
Estou pensando provisoriamente em algo usando RANK, mas posso estar me agarrando a qualquer coisa…
Protótipo inicial...
WITH badge_count AS (
SELECT
user_id,
granted_at,
RANK() OVER (PARTITION BY user_id ORDER BY granted_at ASC) AS rank
FROM user_badges
WHERE badge_id = 110
)
SELECT user_id, granted_at
FROM badge_count
WHERE rank IN (5,10,15,20,25,30,35,40,45,50)
Ok, uma segunda tentativa usando ROW_NUMBER em vez disso:
WITH badge_count AS (
SELECT
user_id,
granted_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY granted_at ASC) AS row
FROM user_badges
WHERE badge_id = 110
)
SELECT user_id, granted_at
FROM badge_count
WHERE row % 5 = 0
Embora, em testes adicionais, isso funcione corretamente na pré-visualização, mas não está sendo concedido várias vezes quando o trabalho real de concessão de distintivo é executado. Não tenho certeza do porquê.
Confundi-me. Vou tomar uma xícara de chá e me reagrupar.
Bem… dei mais 4 bronzes ao meu usuário ontem para ver se a execução noturna pelo menos adicionaria o novo distintivo que ele acabou de “ganhar”. (Eu imaginei que se eu tivesse que atualizar o resto deles manualmente, eu poderia.) Mas nem isso funcionou.
Nem todo mundo tem isso, Toni Você vai deixar as pessoas com inveja. (embora @ganncamp tenha, então é uma opção)
Mas… tenho quase certeza de que minha consulta está correta. Ela seleciona os corretos na Visualização, mas simplesmente não concede mais de um ao usar o gatilho ‘Atualizar Diariamente’.
Configurei outro, quase igual, para testar com base em um distintivo para ‘cada 5 posts em um tópico específico’ usando o gatilho ‘quando um usuário cria ou edita um post’ - e esse funciona perfeitamente. Estou investigando qual pode ser a diferença…
Aqui está o SQL para esse distintivo de teste para comparar, se alguém puder notar algo:
WITH post_count AS (
SELECT
user_id,
id,
created_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at ASC) AS row
FROM posts
WHERE topic_id = 864
)
SELECT user_id, created_at granted_at, id post_id
FROM post_count
WHERE row % 5 = 0
AND (:backfill OR id IN (:post_ids))
Após um pouco de exploração e consulta, parece que o concedente automático de distintivos só concederá vários distintivos se eles forem baseados em posts específicos. Portanto, esses tipos só concederão o primeiro distintivo (a visualização é enganosa ).
Acho que em casos semelhantes distintivos “escalonados” podem funcionar bem (como os Resolvidos). Então uma Prata para 30 e uma Ouro para 100, por exemplo, se essa puder ser uma alternativa viável?
Então… mesmo que os distintivos de bronze sejam concedidos com base em postagens… isso não conta, certo?
Não sei. Acho que não entendi a pergunta.
Acho que a sugestão não é encontrar 5 distintivos, mas 5 postagens onde um distintivo foi concedido? Posso fazer isso. Eu já fiz mais ou menos isso no meu relatório “encontrar novas postagens para conceder distintivos”.
Com base no fato de que o Bronze Badge A é concedido através da ferramenta de postagem ou dando um motivo na página /admin/users/{user_id}/{username}/badges:
WITH badge_count AS (
SELECT
user_id,
granted_at,
post_id,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY granted_at DESC) AS row
FROM user_badges
WHERE badge_id = 110
AND post_id IS NOT NULL
)
SELECT user_id, granted_at, post_id
FROM badge_count
WHERE row % 5 = 0
AND (:backfill OR post_id IN (:post_ids))
(Adicionar AND post_id IS NOT NULL protege contra o caso de alguém ser concedido sem um motivo, caso contrário, quebra)
Bem… quando o trabalho foi executado durante a noite,
meu usuário com 6 bronzes ganhou 1 prata
meu usuário com 13 bronzes ganhou… 1 prata
Esta parte do tutorial me fez pensar que um trabalho de preenchimento separado e explícito não era necessário
Como diariamente um preenchimento completo é executado de qualquer maneira, você deve levar isso em consideração e incluir o tratamento do parâmetro :backfill.
Para usuários que já ganharam mais de 1 prata, como faço para que essas sejam concedidas? Tenho que fazer isso manualmente?
O preenchimento é o trabalho diário. O gatilho ‘Atualizar Diariamente’ é essencialmente isso, enquanto os outros gatilhos são muito mais ‘no momento’ (por exemplo, se um distintivo usasse ‘quando um usuário cria ou edita uma postagem’, não precisaria esperar a noite toda para ser concedido).\n\nVocê pode postar uma captura de tela do seu distintivo para que eu possa ver o que pode ser diferente?\n\n
Eu tinha assumido que o trabalho rodava nas primeiras horas da manhã (da minha parte).
Na verdade, eu tinha originalmente concedido distintivos a este usuário sem motivos, então ontem eu revoguei todos eles, desenterrei postagens dele e concedi novamente. O trabalho rodou no meio do meu processo de concessão.
Isso está no meu site de staging, aliás.
Suponho que o segundo distintivo será concedido em algumas horas, mas eu gostaria de ver vários distintivos concedidos de uma vez. Isso acontecerá se eu revogar o de prata? Ele receberá 2 novas pratas em… 2h?