Implement PartyQueryBuilder in controllers

This commit is contained in:
Justin Edmund 2025-02-12 23:12:13 -08:00
parent 924767457e
commit 412a99a6c7
2 changed files with 67 additions and 28 deletions

View file

@ -105,16 +105,20 @@ module Api
# Lists parties based on query parameters. # Lists parties based on query parameters.
def index def index
query = build_parties_query query = build_filtered_query(build_common_base_query)
@parties = query.paginate(page: params[:page], per_page: COLLECTION_PER_PAGE) @parties = query.paginate(page: params[:page], per_page: COLLECTION_PER_PAGE)
render_paginated_parties(@parties) render_paginated_parties(@parties)
end end
# Lists parties favorited by the current user. # GET /api/v1/parties/favorites
def favorites def favorites
raise Api::V1::UnauthorizedError unless current_user raise Api::V1::UnauthorizedError unless current_user
ap "Total favorites in DB: #{Favorite.count}"
query = build_parties_query(favorites: true) base_query = build_common_base_query
.joins(:favorites)
.where(favorites: { user_id: current_user.id })
.distinct
query = build_filtered_query(base_query)
@parties = query.paginate(page: params[:page], per_page: COLLECTION_PER_PAGE) @parties = query.paginate(page: params[:page], per_page: COLLECTION_PER_PAGE)
render_paginated_parties(@parties) render_paginated_parties(@parties)
end end

View file

@ -55,34 +55,39 @@ module Api
if @user.nil? if @user.nil?
render_not_found_response('user') render_not_found_response('user')
else else
conditions = build_conditions base_query = Party.includes(
conditions[:user_id] = @user.id { raid: :group },
:job,
favorites_query = "EXISTS (SELECT 1 FROM favorites WHERE favorites.party_id = parties.id AND favorites.user_id = #{current_user&.id || 'NULL'}) AS is_favorited" :user,
parties = Party.where(conditions) :skill0,
.where(name_quality) :skill1,
.where(user_quality) :skill2,
.where(original) :skill3,
.where(privacy) :guidebook1,
.includes(:favorites) :guidebook2,
.select(Party.arel_table[Arel.star]) :guidebook3,
.select( { characters: :character },
Arel.sql(favorites_query) { weapons: :weapon },
) { summons: :summon }
.order(created_at: :desc) )
.paginate(page: request.params[:page], per_page: COLLECTION_PER_PAGE) # Restrict to parties belonging to the profile owner
base_query = base_query.where(user_id: @user.id)
count = Party.where(conditions).count skip_privacy = (current_user&.id == @user.id)
query = PartyQueryBuilder.new(
base_query,
params: params,
current_user: current_user,
options: { skip_privacy: skip_privacy }
).build
parties = query.paginate(page: params[:page], per_page: PartyConstants::COLLECTION_PER_PAGE)
count = query.count
render json: UserBlueprint.render(@user, render json: UserBlueprint.render(@user,
view: :profile, view: :profile,
root: 'profile', root: 'profile',
parties: parties, parties: parties,
meta: { meta: { count: count, total_pages: (count.to_f / PartyConstants::COLLECTION_PER_PAGE).ceil, per_page: PartyConstants::COLLECTION_PER_PAGE },
count: count, current_user: current_user
total_pages: count.to_f / COLLECTION_PER_PAGE > 1 ? (count.to_f / COLLECTION_PER_PAGE).ceil : 1, )
per_page: COLLECTION_PER_PAGE
})
end end
end end
@ -98,6 +103,36 @@ module Api
private private
def build_profile_query(profile_user)
query = Party.includes(
{ raid: :group },
:job,
:user,
:skill0,
:skill1,
:skill2,
:skill3,
:guidebook1,
:guidebook2,
:guidebook3,
{ characters: :character },
{ weapons: :weapon },
{ summons: :summon }
)
# Restrict to parties belonging to the profiles owner.
query = query.where(user_id: profile_user.id)
# Then apply the additional filters that we normally use:
query = query.where(name_quality)
.where(user_quality)
.where(original)
.where(privacy)
# And if there are any request-supplied filters, includes, or excludes:
query = apply_filters(query) if params[:filters].present?
query = apply_includes(query, params[:includes]) if params[:includes].present?
query = apply_excludes(query, params[:excludes]) if params[:excludes].present?
query.order(created_at: :desc)
end
def build_conditions def build_conditions
params = request.params params = request.params