diff --git a/app/models/user.rb b/app/models/user.rb index 2d623817cc6..cec9a235c83 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -692,22 +692,27 @@ class User < ActiveRecord::Base end def featured_user_badges(limit=3) - user_badges - .group(:badge_id) - .select(UserBadge.attribute_names.map { |x| "MAX(user_badges.#{x}) AS #{x}" }, - 'COUNT(*) AS "count"', - 'MAX(badges.badge_type_id) AS badges_badge_type_id', - 'MAX(badges.grant_count) AS badges_grant_count') - .joins(:badge) - .order("CASE WHEN user_badges.badge_id = ( - SELECT MAX(ub2.badge_id) - FROM user_badges ub2 - WHERE ub2.badge_id IN (#{Badge.trust_level_badge_ids.join(",")}) - AND ub2.user_id = #{self.id} - ) THEN 1 ELSE 0 END DESC") - .order('badges_badge_type_id ASC, badges_grant_count ASC') - .includes(:user, :granted_by, { badge: :badge_type }, { post: :topic }) - .limit(limit) + tl_badge_ids = Badge.trust_level_badge_ids + + query = user_badges + .group(:badge_id) + .select(UserBadge.attribute_names.map { |x| "MAX(user_badges.#{x}) AS #{x}" }, + 'COUNT(*) AS "count"', + 'MAX(badges.badge_type_id) AS badges_badge_type_id', + 'MAX(badges.grant_count) AS badges_grant_count') + .joins(:badge) + .order('badges_badge_type_id ASC, badges_grant_count ASC, badge_id DESC') + .includes(:user, :granted_by, { badge: :badge_type }, { post: :topic }) + + tl_badge = query.where("user_badges.badge_id IN (:tl_badge_ids)", + tl_badge_ids: tl_badge_ids) + .limit(1) + + other_badges = query.where("user_badges.badge_id NOT IN (:tl_badge_ids)", + tl_badge_ids: tl_badge_ids) + .limit(limit) + + (tl_badge + other_badges).take(limit) end def self.count_by_signup_date(start_date, end_date, group_id=nil) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 3a32c5e4854..5979cb8e4e7 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1346,4 +1346,18 @@ describe User do end end end + + describe "#featured_user_badges" do + let(:user) { Fabricate(:user) } + let!(:user_badge_tl1) { UserBadge.create(badge_id: 1, user: user, granted_by: Discourse.system_user, granted_at: Time.now) } + let!(:user_badge_tl2) { UserBadge.create(badge_id: 2, user: user, granted_by: Discourse.system_user, granted_at: Time.now) } + + it 'should display highest trust level badge first' do + expect(user.featured_user_badges[0].badge_id).to eq(2) + end + + it 'should display only 1 trust level badge' do + expect(user.featured_user_badges.length).to eq(1) + end + end end