Update parties_controller.rb
Adds the rest of the changes, too tired to write them all out. Some preview generation, some filtering
This commit is contained in:
parent
38f6c043bf
commit
234d337af7
1 changed files with 143 additions and 46 deletions
|
|
@ -160,21 +160,56 @@ module Api
|
||||||
current_user: current_user)
|
current_user: current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Lists parties favorited by the current user
|
||||||
|
# @return [void]
|
||||||
def favorites
|
def favorites
|
||||||
raise Api::V1::UnauthorizedError unless current_user
|
raise Api::V1::UnauthorizedError unless current_user
|
||||||
|
|
||||||
conditions = build_filters
|
# Start with base query including relationships and filters
|
||||||
conditions[:favorites] = { user_id: current_user.id }
|
query = Party.includes(
|
||||||
|
{ raid: :group },
|
||||||
|
:job,
|
||||||
|
:user,
|
||||||
|
:skill0,
|
||||||
|
:skill1,
|
||||||
|
:skill2,
|
||||||
|
:skill3,
|
||||||
|
:guidebook1,
|
||||||
|
:guidebook2,
|
||||||
|
:guidebook3,
|
||||||
|
{ characters: :character },
|
||||||
|
{ weapons: :weapon },
|
||||||
|
{ summons: :summon }
|
||||||
|
).joins(:favorites)
|
||||||
|
.where(favorites: { user_id: current_user.id }) # Ensure only favorited parties
|
||||||
|
.order(created_at: :desc) # Show newest first
|
||||||
|
.distinct # Avoid duplicates
|
||||||
|
|
||||||
query = build_query(conditions, favorites: true)
|
# Apply improved filtering logic
|
||||||
|
query = apply_filters(query)
|
||||||
|
query = apply_privacy_settings(query)
|
||||||
query = apply_includes(query, params[:includes]) if params[:includes].present?
|
query = apply_includes(query, params[:includes]) if params[:includes].present?
|
||||||
query = apply_excludes(query, params[:excludes]) if params[:excludes].present?
|
query = apply_excludes(query, params[:excludes]) if params[:excludes].present?
|
||||||
|
|
||||||
@parties = fetch_parties(query)
|
# Paginate results
|
||||||
count = calculate_count(query)
|
@parties = query.paginate(
|
||||||
total_pages = calculate_total_pages(count)
|
page: params[:page],
|
||||||
|
per_page: COLLECTION_PER_PAGE
|
||||||
|
)
|
||||||
|
|
||||||
render_party_json(@parties, count, total_pages)
|
# Mark all as favorited for the current user
|
||||||
|
@parties.each { |party| party.favorited = true }
|
||||||
|
|
||||||
|
render json: PartyBlueprint.render(
|
||||||
|
parties,
|
||||||
|
view: :preview,
|
||||||
|
root: :results,
|
||||||
|
meta: {
|
||||||
|
count: parties.total_entries,
|
||||||
|
total_pages: parties.total_pages,
|
||||||
|
per_page: COLLECTION_PER_PAGE
|
||||||
|
}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# == Preview Management
|
# == Preview Management
|
||||||
|
|
@ -219,6 +254,19 @@ module Api
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns the current status of a party's preview
|
||||||
|
# @return [void]
|
||||||
|
def preview_status
|
||||||
|
party = Party.find_by!(shortcode: params[:id])
|
||||||
|
render json: {
|
||||||
|
state: party.preview_state,
|
||||||
|
generated_at: party.preview_generated_at,
|
||||||
|
ready_for_preview: party.ready_for_preview?
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Forces regeneration of a party's preview image
|
||||||
|
# @return [void]
|
||||||
def regenerate_preview
|
def regenerate_preview
|
||||||
party = Party.find_by!(shortcode: params[:id])
|
party = Party.find_by!(shortcode: params[:id])
|
||||||
|
|
||||||
|
|
@ -268,28 +316,83 @@ module Api
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_filters
|
|
||||||
params = request.params
|
|
||||||
# == Preview Generation
|
# == Preview Generation
|
||||||
|
|
||||||
start_time = build_start_time(params['recency'])
|
# Schedules a background job to generate the party preview
|
||||||
|
# @return [void]
|
||||||
|
def schedule_preview_generation
|
||||||
|
GeneratePartyPreviewJob.perform_later(id)
|
||||||
|
end
|
||||||
|
|
||||||
min_characters_count = build_count(params['characters_count'], DEFAULT_MIN_CHARACTERS)
|
# == Query Building Helpers
|
||||||
min_summons_count = build_count(params['summons_count'], DEFAULT_MIN_SUMMONS)
|
|
||||||
min_weapons_count = build_count(params['weapons_count'], DEFAULT_MIN_WEAPONS)
|
|
||||||
max_clear_time = build_max_clear_time(params['max_clear_time'])
|
|
||||||
|
|
||||||
|
def apply_filters(query)
|
||||||
|
conditions = build_filters
|
||||||
|
|
||||||
|
# Use the compound indexes effectively
|
||||||
|
query = query.where(conditions)
|
||||||
|
.where(name_quality) if params[:name_quality].present?
|
||||||
|
|
||||||
|
# Use the counters index
|
||||||
|
query = query.where(
|
||||||
|
weapons_count: build_count(params[:weapons_count], DEFAULT_MIN_WEAPONS)..MAX_WEAPONS,
|
||||||
|
characters_count: build_count(params[:characters_count], DEFAULT_MIN_CHARACTERS)..MAX_CHARACTERS,
|
||||||
|
summons_count: build_count(params[:summons_count], DEFAULT_MIN_SUMMONS)..MAX_SUMMONS
|
||||||
|
)
|
||||||
|
|
||||||
|
query
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply_privacy_settings(query)
|
||||||
|
return query if admin_mode
|
||||||
|
|
||||||
|
if params[:favorites].present?
|
||||||
|
query.where('visibility < 3')
|
||||||
|
else
|
||||||
|
query.where(visibility: 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Builds filter conditions from request parameters
|
||||||
|
# @return [Hash] conditions for the query
|
||||||
|
def build_filters
|
||||||
{
|
{
|
||||||
element: build_element(params['element']),
|
element: params[:element].present? ? params[:element].to_i : nil,
|
||||||
raid: params['raid'],
|
raid_id: params[:raid],
|
||||||
created_at: params['recency'].present? ? start_time..DateTime.current : nil,
|
created_at: build_date_range,
|
||||||
full_auto: build_option(params['full_auto']),
|
full_auto: build_option(params[:full_auto]),
|
||||||
auto_guard: build_option(params['auto_guard']),
|
auto_guard: build_option(params[:auto_guard]),
|
||||||
charge_attack: build_option(params['charge_attack']),
|
charge_attack: build_option(params[:charge_attack]),
|
||||||
characters_count: min_characters_count..MAX_CHARACTERS,
|
characters_count: build_count(params[:characters_count], DEFAULT_MIN_CHARACTERS)..MAX_CHARACTERS,
|
||||||
summons_count: min_summons_count..MAX_SUMMONS,
|
summons_count: build_count(params[:summons_count], DEFAULT_MIN_SUMMONS)..MAX_SUMMONS,
|
||||||
weapons_count: min_weapons_count..MAX_WEAPONS
|
weapons_count: build_count(params[:weapons_count], DEFAULT_MIN_WEAPONS)..MAX_WEAPONS
|
||||||
}.delete_if { |_k, v| v.nil? }
|
}.compact
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_date_range
|
||||||
|
return nil unless params[:recency].present?
|
||||||
|
|
||||||
|
start_time = DateTime.current - params[:recency].to_i.seconds
|
||||||
|
start_time.beginning_of_day..DateTime.current
|
||||||
|
end
|
||||||
|
|
||||||
|
# Paginates the given query of parties and marks favorites for the current user
|
||||||
|
#
|
||||||
|
# @param query [ActiveRecord::Relation] The base query containing parties
|
||||||
|
# @param page [Integer, nil] The page number for pagination (defaults to `params[:page]`)
|
||||||
|
# @param per_page [Integer] The number of records per page (defaults to `COLLECTION_PER_PAGE`)
|
||||||
|
# @return [ActiveRecord::Relation] The paginated and processed list of parties
|
||||||
|
#
|
||||||
|
# This method orders parties by creation date in descending order, applies pagination,
|
||||||
|
# and marks each party as favorited if the current user has favorited it.
|
||||||
|
def paginate_parties(query, page: nil, per_page: COLLECTION_PER_PAGE)
|
||||||
|
query.order(created_at: :desc)
|
||||||
|
.paginate(page: page || params[:page], per_page: per_page)
|
||||||
|
.tap do |parties|
|
||||||
|
if current_user
|
||||||
|
parties.each { |party| party.favorited = party.is_favorited(current_user) }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# == Parameter Processing Helpers
|
# == Parameter Processing Helpers
|
||||||
|
|
@ -409,9 +512,7 @@ module Api
|
||||||
query = query.where(condition, id)
|
query = query.where(condition, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
query.where(characters_subquery.exists.not)
|
query
|
||||||
.where(weapons_subquery.exists.not)
|
|
||||||
.where(summons_subquery.exists.not)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# == Query Filtering Helpers
|
# == Query Filtering Helpers
|
||||||
|
|
@ -456,7 +557,7 @@ module Api
|
||||||
# @return [ActiveRecord::Relation] processed and paginated parties
|
# @return [ActiveRecord::Relation] processed and paginated parties
|
||||||
def fetch_parties(query)
|
def fetch_parties(query)
|
||||||
query.order(created_at: :desc)
|
query.order(created_at: :desc)
|
||||||
.paginate(page: request.params[:page], per_page: COLLECTION_PER_PAGE)
|
.paginate(page: params[:page], per_page: COLLECTION_PER_PAGE)
|
||||||
.each { |party| party.favorited = current_user ? party.is_favorited(current_user) : false }
|
.each { |party| party.favorited = current_user ? party.is_favorited(current_user) : false }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -472,28 +573,24 @@ module Api
|
||||||
# @param count [Integer] total record count
|
# @param count [Integer] total record count
|
||||||
# @return [Integer] total pages
|
# @return [Integer] total pages
|
||||||
def calculate_total_pages(count)
|
def calculate_total_pages(count)
|
||||||
count.to_f / COLLECTION_PER_PAGE > 1 ? (count.to_f / COLLECTION_PER_PAGE).ceil : 1
|
# count.to_f / COLLECTION_PER_PAGE > 1 ? (count.to_f / COLLECTION_PER_PAGE).ceil : 1
|
||||||
|
(count.to_f / COLLECTION_PER_PAGE).ceil
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_party_json(parties, count, total_pages)
|
# == Include/Exclude Processing
|
||||||
render json: PartyBlueprint.render(parties,
|
|
||||||
view: :collection,
|
# Generates SQL for including specific items
|
||||||
root: :results,
|
# @param id [String] item identifier
|
||||||
meta: {
|
# @return [String] SQL condition
|
||||||
count: count,
|
def includes(id)
|
||||||
total_pages: total_pages,
|
"(\"#{id_to_table(id)}\".\"granblue_id\" = '#{id}')"
|
||||||
per_page: COLLECTION_PER_PAGE
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def privacy(favorites: false)
|
# Generates SQL for excluding specific items
|
||||||
return if admin_mode
|
# @param id [String] item identifier
|
||||||
|
# @return [String] SQL condition
|
||||||
if favorites
|
def excludes(id)
|
||||||
'visibility < 3'
|
"(\"#{id_to_table(id)}\".\"granblue_id\" != '#{id}')"
|
||||||
else
|
|
||||||
'visibility = 1'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# == Filter Condition Helpers
|
# == Filter Condition Helpers
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue