Como excluir direitos a um emblema personalizado se um nível superior já foi concedido? O objetivo é conceder apenas o nível mais alto para o qual um determinado usuário é elegível…
Digamos que eu tenha 3 emblemas:
Nível 1: 5 curtidas dadas, 5 recebidas
Nível 2: 100 curtidas dadas, 100 recebidas
Nível 3: 250 curtidas dadas, 250 recebidas
O código abaixo é para o Nível 2. Outros níveis não têm nada diferente além do número ‘100’
SELECT us.user_id, current_timestamp AS granted_at
FROM user_stats AS us
WHERE us.likes_received >= 100
AND us.likes_given >= 100
AND (:backfill OR us.user_id IN (:user_ids))
Nas configurações /admin/badges/BADGE-ID, basta marcar a opção Executar consulta de revogação diariamente. O distintivo será removido se o usuário não atender mais aos critérios SQL.
Você também pode querer definir a opção Atualizar diariamente para que a concessão/revogação ocorra aproximadamente ao mesmo tempo (meia-noite, horário local da sua instância, eu acho).
Isso também precisaria de uma linha extra no SQL do emblema para equilibrar? Algo como:
SELECT us.user_id, current_timestamp AS granted_at
FROM user_stats AS us
WHERE us.likes_received >= 100
AND us.likes_given >= 100
AND us.likes_given < 250
AND (:backfill OR us.user_id IN (:user_ids))
(possivelmente usar um BETWEEN ou similar, embora eu ainda não tenha testado isso )
E então, quando a consulta for executada, ela concederá o emblema para 100 curtidas pela primeira vez, o ignorará para 101 a 249 e, em seguida, o revogará em 250 (de onde o próximo emblema continuará).
Atualização: Pratiquei um pouco com BETWEEN e algo como isto parece capturar todas as pessoas certas no teste de amostra:
SELECT us.user_id
FROM user_stats AS us
WHERE us.likes_received BETWEEN 100 AND 249
ORDER BY us.likes_received DESC
Portanto, algo como isto deve funcionar se convertido em um emblema acionado:
SELECT us.user_id, current_timestamp AS granted_at
FROM user_stats AS us
WHERE us.likes_received BETWEEN 100 AND 249
AND us.likes_given BETWEEN 100 AND 249
AND (:backfill OR us.user_id IN (:user_ids))
Isso está quase perfeito. Um evento raro pode ocorrer: o usuário entrega demais em ‘dado’ enquanto fica para trás em ‘recebido’ (ou vice-versa), então o distintivo pode ser perdido antes que o próximo seja concedido (rotina de revogação).
Pesquisei e descobri uma propriedade interessante: something.badge_id = 123 onde ‘something’ é a variável definida pelo usuário e ‘123’ o ID de outro distintivo. Vou tentar e complementar os SQLs originais do Nível 1 e Nível 2 com verificações de desqualificação contra os distintivos de nível superior.