discourse/app/controllers/user_actions_controller.rb
Alan Guo Xiang Tan 2032d3c2fb
PERF: Preload user information when visiting user messages routes (#21929)
What is the problem?

The user messages routes are currently routed by the server to
`UserActionsController#private_messages`. However, the method is
essentially a no-op and does not do any preloading. As a result, when we
load the user private messages routes, the client ends up having to
issue another request to the server to get more information about the
user profile currently being viewed. This extra request is triggered by
the `user` model's `findDetails` method that is called from the `user`
route in the `afterModel` hook.

What is the solution?

The `user` model's `findDetails` method actually checks the preload
store to see if the `user_${username}` key is present in the store and
if it is, it will use the preloaded data instead of triggering another
request. Since the user private messages routes are nested under the
user route on the client side, we have to rely on the
`UsersController#show` controller action on the server side for the user private
messages route as the `UsersController#show` controller action preloads
the required user information for the client side.
2023-06-05 19:24:22 +08:00

45 lines
1.3 KiB
Ruby

# frozen_string_literal: true
class UserActionsController < ApplicationController
def index
user_actions_params.require(:username)
user =
fetch_user_from_params(
include_inactive:
current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts),
)
offset = [0, user_actions_params[:offset].to_i].max
action_types = (user_actions_params[:filter] || "").split(",").map(&:to_i)
limit = user_actions_params.fetch(:limit, 30).to_i
raise Discourse::NotFound unless guardian.can_see_profile?(user)
raise Discourse::NotFound unless guardian.can_see_user_actions?(user, action_types)
opts = {
user_id: user.id,
user: user,
offset: offset,
limit: limit,
action_types: action_types,
guardian: guardian,
ignore_private_messages: params[:filter].blank?,
acting_username: params[:acting_username],
}
stream = UserAction.stream(opts).to_a
render_serialized(stream, UserActionSerializer, root: "user_actions")
end
def show
params.require(:id)
render_serialized(UserAction.stream_item(params[:id], guardian), UserActionSerializer)
end
private
def user_actions_params
@user_actions_params ||= params.permit(:username, :filter, :offset, :acting_username, :limit)
end
end