PERF: N+1 queries admin users pages.

This commit is contained in:
Guo Xiang Tan 2019-03-15 14:59:16 +08:00
parent d6d4a5ba4a
commit c5808a8a25
4 changed files with 29 additions and 11 deletions

View File

@ -69,6 +69,11 @@ class User < ActiveRecord::Base
has_many :oauth2_user_infos, dependent: :destroy
has_one :instagram_user_info, dependent: :destroy
has_many :user_second_factors, dependent: :destroy
has_many :totps, -> {
where(method: UserSecondFactor.methods[:totp], enabled: true)
}, class_name: "UserSecondFactor"
has_one :user_stat, dependent: :destroy
has_one :user_profile, dependent: :destroy, inverse_of: :user
has_one :single_sign_on_record, dependent: :destroy

View File

@ -119,7 +119,9 @@ class AdminUserListSerializer < BasicUserSerializer
end
def include_second_factor_enabled?
object.totp_enabled?
!SiteSetting.enable_sso &&
SiteSetting.enable_local_logins &&
object.totps.present?
end
def second_factor_enabled

View File

@ -60,12 +60,15 @@ class AdminUserIndexQuery
order << "users.username"
end
if params[:stats].present? && params[:stats] == false
klass.order(order.reject(&:blank?).join(","))
else
klass.includes(:user_stat, :user_second_factors)
.order(order.reject(&:blank?).join(","))
query = klass
.includes(:totps)
.order(order.reject(&:blank?).join(","))
unless params[:stats].present? && params[:stats] == false
query = query.includes(:user_stat)
end
query
end
def filter_by_trust

View File

@ -2,16 +2,24 @@ require 'rails_helper'
require_dependency 'user'
describe AdminUserListSerializer do
let(:user) { Fabricate(:user_second_factor_totp).user }
let(:admin) { Fabricate(:admin) }
let(:guardian) { Guardian.new(admin) }
let(:serializer) do
AdminUserListSerializer.new(user, scope: guardian, root: false)
end
it "returns the right values when user has second factor totp enabled" do
json = serializer.as_json
expect(json[:second_factor_enabled]).to eq(true)
end
context "emails" do
let(:admin) { Fabricate(:user_single_email, admin: true, email: "admin@email.com") }
let(:moderator) { Fabricate(:user_single_email, moderator: true, email: "moderator@email.com") }
let(:user) { Fabricate(:user_single_email, email: "user@email.com") }
let(:guardian) { Guardian.new(admin) }
let(:serializer) do
AdminUserListSerializer.new(user, scope: guardian, root: false)
end
def serialize(user, viewed_by, opts = nil)
AdminUserListSerializer.new(