diff --git a/app/services/badge_granter.rb b/app/services/badge_granter.rb index 33d01fc6b..921d228b5 100644 --- a/app/services/badge_granter.rb +++ b/app/services/badge_granter.rb @@ -74,7 +74,7 @@ class BadgeGranter LEFT JOIN ( #{badge.query} ) q ON q.user_id = ub.user_id #{post_clause} - WHERE ub.id = :id AND q.user_id IS NULL + WHERE ub.badge_id = :id AND q.user_id IS NULL )" Badge.exec_sql(sql, id: badge.id) @@ -83,9 +83,9 @@ class BadgeGranter SELECT :id, q.user_id, q.granted_at, -1, #{post_id_field} FROM ( #{badge.query} ) q LEFT JOIN user_badges ub ON - ub.id = :id AND ub.user_id = q.user_id + ub.badge_id = :id AND ub.user_id = q.user_id #{post_clause} - WHERE ub.id IS NULL" + WHERE ub.badge_id IS NULL" Badge.exec_sql(sql, id: badge.id) diff --git a/db/migrate/20140705081453_index_user_badges.rb b/db/migrate/20140705081453_index_user_badges.rb new file mode 100644 index 000000000..332fc1718 --- /dev/null +++ b/db/migrate/20140705081453_index_user_badges.rb @@ -0,0 +1,11 @@ +class IndexUserBadges < ActiveRecord::Migration + def change + execute 'DELETE FROM user_badges USING user_badges ub2 + WHERE user_badges.badge_id = ub2.badge_id AND + user_badges.user_id = ub2.user_id AND + user_badges.post_id IS NOT NULL AND + user_badges.id < ub2.id + ' + add_index :user_badges, [:badge_id, :user_id, :post_id], unique: true, where: 'post_id IS NOT NULL' + end +end diff --git a/spec/services/badge_granter_spec.rb b/spec/services/badge_granter_spec.rb index c16f1b378..99588e0e8 100644 --- a/spec/services/badge_granter_spec.rb +++ b/spec/services/badge_granter_spec.rb @@ -28,8 +28,10 @@ describe BadgeGranter do it 'should grant missing badges' do post = Fabricate(:post, like_count: 30) - BadgeGranter.backfill(Badge.find(Badge::NicePost)) - BadgeGranter.backfill(Badge.find(Badge::GoodPost)) + 2.times { + BadgeGranter.backfill(Badge.find(Badge::NicePost)) + BadgeGranter.backfill(Badge.find(Badge::GoodPost)) + } # TODO add welcome post.user.user_badges.pluck(:badge_id).sort.should == [Badge::NicePost,Badge::GoodPost]