PERF: fix performance issue when displaying the user card for admins

This commit is contained in:
Régis Hanol 2015-01-05 19:49:32 +01:00
parent 47c4179e29
commit e20078a9dc
7 changed files with 62 additions and 38 deletions

View file

@ -353,6 +353,14 @@ Discourse.User = Discourse.Model.extend({
}); });
}, },
findStaffInfo: function() {
if (!Discourse.User.currentProp("staff")) { return Ember.RSVP.resolve(null); }
var self = this;
return Discourse.ajax("/users/" + this.get("username_lower") + "/staff-info.json").then(function(info) {
self.setProperties(info);
});
},
avatarTemplate: function() { avatarTemplate: function() {
return Discourse.User.avatarTemplate(this.get('username'), this.get('uploaded_avatar_id')); return Discourse.User.avatarTemplate(this.get('username'), this.get('uploaded_avatar_id'));
}.property('uploaded_avatar_id', 'username'), }.property('uploaded_avatar_id', 'username'),

View file

@ -45,7 +45,10 @@ export default Discourse.Route.extend({
}, },
afterModel: function() { afterModel: function() {
return this.modelFor('user').findDetails(); var user = this.modelFor('user');
return user.findDetails().then(function() {
return user.findStaffInfo();
});
}, },
serialize: function(model) { serialize: function(model) {

View file

@ -512,6 +512,19 @@ class UsersController < ApplicationController
render json: success_json render json: success_json
end end
def staff_info
@user = fetch_user_from_params
guardian.ensure_can_see_staff_info!(@user)
result = {}
%W{number_of_deleted_posts number_of_flagged_posts number_of_flags_given number_of_suspensions number_of_warnings}.each do |info|
result[info] = @user.send(info)
end
render json: result
end
private private
def honeypot_value def honeypot_value

View file

@ -803,6 +803,38 @@ class User < ActiveRecord::Base
end end
end end
def number_of_deleted_posts
Post.with_deleted
.where(user_id: self.id)
.where(user_deleted: false)
.where.not(deleted_by_id: self.id)
.where.not(deleted_at: nil)
.count
end
def number_of_flagged_posts
Post.with_deleted
.where(user_id: self.id)
.where(id: PostAction.where(post_action_type_id: PostActionType.notify_flag_type_ids)
.where(disagreed_at: nil)
.select(:post_id))
.count
end
def number_of_flags_given
PostAction.where(user_id: self.id)
.where(post_action_type_id: PostActionType.notify_flag_type_ids)
.count
end
def number_of_warnings
self.warnings.count
end
def number_of_suspensions
UserHistory.for(self, :suspend_user).count
end
private private
def previous_visit_at_update_required?(timestamp) def previous_visit_at_update_required?(timestamp)

View file

@ -68,11 +68,6 @@ class UserSerializer < BasicUserSerializer
has_one :card_badge, embed: :object, serializer: BadgeSerializer has_one :card_badge, embed: :object, serializer: BadgeSerializer
staff_attributes :post_count, staff_attributes :post_count,
:number_of_deleted_posts,
:number_of_flagged_posts,
:number_of_flags_given,
:number_of_suspensions,
:number_of_warnings,
:can_be_deleted, :can_be_deleted,
:can_delete_all_posts :can_delete_all_posts
@ -219,38 +214,6 @@ class UserSerializer < BasicUserSerializer
object.user_stat.try(:post_count) object.user_stat.try(:post_count)
end end
def number_of_deleted_posts
Post.with_deleted
.where(user_id: object.id)
.where(user_deleted: false)
.where.not(deleted_by_id: object.id)
.where.not(deleted_at: nil)
.count
end
def number_of_flagged_posts
Post.with_deleted
.where(user_id: object.id)
.where(id: PostAction.where(post_action_type_id: PostActionType.notify_flag_type_ids)
.where(disagreed_at: nil)
.select(:post_id))
.count
end
def number_of_flags_given
PostAction.where(user_id: object.id)
.where(post_action_type_id: PostActionType.notify_flag_type_ids)
.count
end
def number_of_warnings
object.warnings.count
end
def number_of_suspensions
UserHistory.for(object, :suspend_user).count
end
def can_be_deleted def can_be_deleted
scope.can_delete_user?(object) scope.can_delete_user?(object)
end end

View file

@ -242,6 +242,7 @@ Discourse::Application.routes.draw do
put "users/:username/preferences/avatar/pick" => "users#pick_avatar", constraints: {username: USERNAME_ROUTE_FORMAT} put "users/:username/preferences/avatar/pick" => "users#pick_avatar", constraints: {username: USERNAME_ROUTE_FORMAT}
get "users/:username/preferences/card-badge" => "users#card_badge", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/preferences/card-badge" => "users#card_badge", constraints: {username: USERNAME_ROUTE_FORMAT}
put "users/:username/preferences/card-badge" => "users#update_card_badge", constraints: {username: USERNAME_ROUTE_FORMAT} put "users/:username/preferences/card-badge" => "users#update_card_badge", constraints: {username: USERNAME_ROUTE_FORMAT}
get "users/:username/staff-info" => "users#staff_info", constraints: {username: USERNAME_ROUTE_FORMAT}
get "users/:username/invited" => "users#invited", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/invited" => "users#invited", constraints: {username: USERNAME_ROUTE_FORMAT}
post "users/action/send_activation_email" => "users#send_activation_email" post "users/action/send_activation_email" => "users#send_activation_email"

View file

@ -55,4 +55,8 @@ module UserGuardian
user.trust_level == TrustLevel[0] && anonymous? user.trust_level == TrustLevel[0] && anonymous?
end end
def can_see_staff_info?(user)
user && is_staff?
end
end end