diff --git a/app/assets/javascripts/discourse/templates/badges/show.js.handlebars b/app/assets/javascripts/discourse/templates/badges/show.js.handlebars index d97eaeb7ea2..5cbac9db05d 100644 --- a/app/assets/javascripts/discourse/templates/badges/show.js.handlebars +++ b/app/assets/javascripts/discourse/templates/badges/show.js.handlebars @@ -27,6 +27,7 @@ {{/link-to}} + {{/each}} {{#if canLoadMore}} diff --git a/app/jobs/regular/update_badges.rb b/app/jobs/regular/update_badges.rb index 3432b02e676..644118b8bac 100644 --- a/app/jobs/regular/update_badges.rb +++ b/app/jobs/regular/update_badges.rb @@ -28,7 +28,7 @@ module Jobs # Grant "Welcome" badge to the user if they do not already have it. BadgeGranter.grant(Badge.find(5), user) - [{id: 6, count: 10}, {id: 7, count: 25}, {id: 8, count: 100}].each do |b| + Badge.like_badge_info.each do |b| if post.like_count >= b[:count] BadgeGranter.grant(Badge.find(b[:id]), user, post_id: post.id) else diff --git a/app/models/badge.rb b/app/models/badge.rb index d090c61a25f..a631db58f51 100644 --- a/app/models/badge.rb +++ b/app/models/badge.rb @@ -7,6 +7,11 @@ class Badge < ActiveRecord::Base validates :allow_title, inclusion: [true, false] validates :multiple_grant, inclusion: [true, false] + Welcome = 5 + NicePost = 6 + GoodPost = 7 + GreatPost = 8 + def self.trust_level_badge_ids (1..4).to_a end @@ -20,6 +25,14 @@ class Badge < ActiveRecord::Base !self.multiple_grant? end + def self.like_badge_info + [ + {id: NicePost, count: 10}, + {id: GoodPost, count: 25}, + {id: GreatPost, count: 100} + ] + end + end # == Schema Information diff --git a/app/serializers/user_badge_serializer.rb b/app/serializers/user_badge_serializer.rb index 561b26f4476..4f67731a256 100644 --- a/app/serializers/user_badge_serializer.rb +++ b/app/serializers/user_badge_serializer.rb @@ -1,5 +1,5 @@ class UserBadgeSerializer < ApplicationSerializer - attributes :id, :granted_at, :count, :post_id + attributes :id, :granted_at, :count, :post_id, :post_number has_one :badge has_one :user, serializer: BasicUserSerializer, root: :users @@ -11,10 +11,15 @@ class UserBadgeSerializer < ApplicationSerializer end def include_post_id? - !object.post_id.nil? + object.post_id && object.post end + alias :include_topic? :include_post_id? + def post_number + object.post && object.post.post_number + end + def topic object.post.topic end diff --git a/app/services/badge_granter.rb b/app/services/badge_granter.rb index 2bca12c518f..1b543dcc121 100644 --- a/app/services/badge_granter.rb +++ b/app/services/badge_granter.rb @@ -55,4 +55,49 @@ class BadgeGranter Jobs.enqueue(:update_badges, args) end + + def self.backfill_like_badges + Badge.like_badge_info.each do |info| + sql = " + DELETE FROM user_badges + WHERE badge_id = :id AND + NOT EXISTS (SELECT 1 FROM posts p + JOIN topics t on p.topic_id = t.id + WHERE p.deleted_at IS NULL AND + t.deleted_at IS NULL AND + t.visible AND + post_id = p.id AND + p.like_count >= :count + ) + " + + Badge.exec_sql(sql, info) + + sql = " + INSERT INTO user_badges(badge_id, user_id, granted_at, granted_by_id, post_id) + SELECT :id, p.user_id, :now, -1, p.id + FROM posts p + JOIN topics t on p.topic_id = t.id + WHERE p.deleted_at IS NULL AND + t.deleted_at IS NULL AND + t.visible AND + p.like_count >= :count AND + NOT EXISTS (SELECT 1 FROM user_badges ub + WHERE ub.post_id = p.id AND + ub.badge_id = :id AND + ub.user_id = p.user_id) + " + + Badge.exec_sql(sql, info.merge(now: Time.now)) + + sql = " + UPDATE badges b + SET grant_count = (SELECT COUNT(*) FROM user_badges WHERE badge_id = :id) + WHERE b.id = :id + " + + Badge.exec_sql(sql, info) + end + end + end diff --git a/spec/services/badge_granter_spec.rb b/spec/services/badge_granter_spec.rb index a8f8499ff20..6fc10efb93b 100644 --- a/spec/services/badge_granter_spec.rb +++ b/spec/services/badge_granter_spec.rb @@ -9,6 +9,19 @@ describe BadgeGranter do SiteSetting.enable_badges = true end + describe 'backfill like badges' do + it 'should grant missing badges' do + post = Fabricate(:post, like_count: 30) + BadgeGranter.backfill_like_badges + + # TODO add welcome + post.user.user_badges.pluck(:badge_id).sort.should == [Badge::NicePost,Badge::GoodPost] + + Badge.find(Badge::NicePost).grant_count.should == 1 + Badge.find(Badge::GoodPost).grant_count.should == 1 + end + end + describe 'grant' do it 'grants a badge' do