Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create the rankings page on rails! #4394

Merged
merged 1 commit into from Aug 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions WcaOnRails/app/assets/stylesheets/application.css.scss
Expand Up @@ -38,6 +38,7 @@
@import "regional_organizations";
@import "users";
@import "competitions";
@import "results";
@import "registrations";
@import "wca-autocomplete";
@import "collapsible-panels";
Expand Down
19 changes: 19 additions & 0 deletions WcaOnRails/app/assets/stylesheets/results.scss
@@ -0,0 +1,19 @@
#results-selector {
width: 100%;
margin: 20px 0;

#event,
#region,
#type,
#years,
#show {
font-size: 12px;
font-weight: normal;
display: block;
min-width: 165px;
@media (max-width: $screen-sm) {
display: inline-block;
width: 100%;
}
}
}
18 changes: 18 additions & 0 deletions WcaOnRails/app/assets/stylesheets/wca.scss
Expand Up @@ -155,6 +155,11 @@ table.wca-results {
&.single {
text-align: right;
}
&.result {
text-align: right;
}
&.region {
}
}
tbody tr td {
padding: 3px 5px;
Expand Down Expand Up @@ -190,6 +195,15 @@ table.wca-results {
&.single {
text-align: right;
}
&.result {
text-align: right;
font-weight: bold;
}
&.region {
&.tied-previous {
@extend .text-muted;
}
}
}

tbody tr.sort-by-average td {
Expand Down Expand Up @@ -350,6 +364,10 @@ textarea {
cursor: pointer;
}
}

a.active {
color: $blue;
}
}

// _associated_events_picker.html.erb specific styles
Expand Down
243 changes: 243 additions & 0 deletions WcaOnRails/app/controllers/results_controller.rb
@@ -0,0 +1,243 @@
# frozen_string_literal: true

class ResultsController < ApplicationController
def rankings
support_old_links!

# Default params
params[:region] ||= "world"
params[:years] ||= "all years"
params[:show] ||= "100 persons"

@years = Competition.non_future_years

@quantities = ["100", "1000"]

@types = ["single", "average"]
if !@types.include?(params[:type])
flash[:danger] = t(".unknown_type")
return redirect_to results_rankings_path(params[:event_id], "single")
end
@is_average = params[:type] == @types[1]
value = @is_average ? "average" : "best"
capitalized_type_param = params[:type].capitalize

event = Event.c_find!(params[:event_id])
event_condition = "AND eventId = '#{event.id}'"
event_condition_without_and = "eventId = '#{event.id}'"

@is_by_region = params[:show] == "by region"
splitted_show_param = params[:show].split
@show = splitted_show_param[0].to_i
@is_persons = splitted_show_param[1] == "persons"
@is_results = splitted_show_param[1] == "results"
limit_condition = "LIMIT #{@show}"

id_string = @is_results ? ".id" : "Id"
@continent = Continent.c_find(params[:region])
@country = Country.c_find(params[:region])
if @continent.present?
region_condition = "AND continentId = '#{@continent.id}'"
elsif @country.present?
region_condition = "AND country#{id_string} = '#{@country.id}'"
else
region_condition = ""
end

@is_all_years = params[:years] == "all years"
splitted_years_param = params[:years].split
@is_only = splitted_years_param[0] == "only"
@is_until = splitted_years_param[0] == "until"
@year = splitted_years_param[1].to_i
if @is_only
years_condition = "AND year = #{@year}"
elsif @is_until
years_condition = "AND year <= #{@year}"
else
years_condition = ""
end

if @is_persons
query = <<-SQL
SELECT result.*,
result.#{value} value,
competition.cellName competitionName,
country.name countryName
FROM
(SELECT MIN(valueAndId) valueAndId
FROM Concise#{capitalized_type_param}Results result
WHERE #{value} > 0
#{event_condition}
#{years_condition}
#{region_condition}
GROUP BY personId
ORDER BY valueAndId
#{limit_condition}) top,
Results result,
Competitions competition,
Countries country
WHERE
result.id = valueAndId % 1000000000
AND competition.id = competitionId
AND country.id = result.countryId
ORDER BY
value, personName
SQL
elsif @is_results
if @is_average
query = <<-SQL
SELECT result.*,
result.#{value} value,
competition.cellName competitionName,
country.name countryName
FROM
Results result,
Competitions competition,
Countries country
WHERE #{value} > 0
#{event_condition}
#{years_condition}
#{region_condition}
AND competition.id = competitionId
AND country.id = result.countryId
ORDER BY
value, best, personName, competitionId, roundTypeId
#{limit_condition}
SQL
else
subqueries = []
(1..5).each do |i|
subqueries[i-1] = <<-SQL
SELECT
value#{i} value,
personId, personName,
country.id countryId,
competitionId,
competition.cellName competitionName,
roundTypeId
FROM
Results result,
Competitions competition,
Countries country
WHERE value#{i} > 0
#{event_condition}
#{years_condition}
#{region_condition}
AND competition.id = competitionId
AND country.id = result.countryId
ORDER BY
value, personName
#{limit_condition}
SQL
end
subquery = ("(" + subqueries.join(") UNION ALL (") + ")")

query = <<-SQL
SELECT *
FROM
(#{subquery}) result
ORDER BY
value, personName, competitionId, roundTypeId
#{limit_condition}
SQL
end
elsif @is_by_region
query = <<-SQL
SELECT
result.personId personId,
result.personName personName,
result.eventId eventId,
result.formatId formatId,
result.roundTypeId roundTypeId,
country.id countryId,
country.name countryName,
continent.id continentId,
continent.name continentName,
competition.id competitionId,
competition.cellName competitionName,
#{value} value,
event.format valueFormat,
value1, value2, value3, value4, value5
FROM
(SELECT countryId recordCountryId, MIN(#{value}) recordValue
FROM Concise#{capitalized_type_param}Results result
WHERE 1
#{event_condition}
#{years_condition}
GROUP BY countryId) record,
Results result,
Countries country,
Continents continent,
Competitions competition,
Events event
WHERE
#{event_condition_without_and}
#{years_condition}
AND result.#{value} = recordValue
AND result.countryId = recordCountryId
AND country.id = result.countryId
AND continent.id = continentId
AND competition.id = competitionId
AND event.id = eventId
ORDER BY
value, countryId, year, month, day, personName
SQL
else
flash[:danger] = t(".unknown_show")
AlbertoPdRF marked this conversation as resolved.
Show resolved Hide resolved
return redirect_to results_rankings_path
end

@rows = ActiveRecord::Base.connection.exec_query(query)
compute_rankings_by_region if @is_by_region
end

def compute_rankings_by_region
best_value_of_world = @rows.first["value"]
best_values_of_continents = {}
best_values_of_countries = {}
world_rows = []
continents_rows = []
countries_rows = []
@rows.each do |row|
result = LightResult.new(row)
value = row["value"]

world_rows << row if value == best_value_of_world

if best_values_of_continents[result.country.continent.id].nil? || value == best_values_of_continents[result.country.continent.id]
best_values_of_continents[result.country.continent.id] = value

if (@country.present? && @country.continent.id == result.country.continent.id) || (@continent.present? && @continent.id == result.country.continent.id) || params[:region] == "world"
continents_rows << row
end
end

if best_values_of_countries[result.country.id].nil? || value == best_values_of_countries[result.country.id]
best_values_of_countries[result.country.id] = value

if (@country.present? && @country.id == result.country.id) || params[:region] == "world"
countries_rows << row
end
end
end

@first_continent_index = world_rows.length
@first_country_index = @first_continent_index + continents_rows.length
@rows_to_display = world_rows + continents_rows + countries_rows
end

# Normalizes the params so that old links to rankings still work.
private def support_old_links!
params[:years]&.gsub!("+", " ")
if params[:years] == "all"
params[:years] = nil
end
AlbertoPdRF marked this conversation as resolved.
Show resolved Hide resolved

params[:show]&.gsub!("+", " ")
params[:show]&.downcase!
# We are not supporting the all option anymore!
if params[:show]&.include?("all")
params[:show] = nil
end
end
end
4 changes: 2 additions & 2 deletions WcaOnRails/app/helpers/application_helper.rb
Expand Up @@ -155,13 +155,13 @@ def year_option_tags(selected_year: nil, exclude_future: true)
options_for_select(years, selected_year)
end

def region_option_tags(selected_id: nil, real_only: false)
def region_option_tags(selected_id: nil, real_only: false, use_world: false)
regions = {
t('common.continent') => Continent.all_sorted_by(I18n.locale, real: real_only).map { |continent| [continent.name, continent.id] },
t('common.country') => Country.all_sorted_by(I18n.locale, real: real_only).map { |country| [country.name, country.id] },
}

options_for_select([[t('common.all_regions'), "all"]], selected_id) + grouped_options_for_select(regions, selected_id)
options_for_select((use_world ? [[t('common.world'), "world"]] : [[t('common.all_regions'), "all"]]), selected_id) + grouped_options_for_select(regions, selected_id)
end

def simple_form_for(resource, options = {}, &block)
Expand Down
2 changes: 1 addition & 1 deletion WcaOnRails/app/models/competition.rb
Expand Up @@ -994,7 +994,7 @@ def events_with_round_types_with_results
ActiveRecord::Base.connection
.execute(relation.to_sql)
.each(as: :hash).map { |r|
LightResult.new(r, Country.c_find(r["countryId"]), Format.c_find(r["formatId"]), RoundType.c_find(r["roundTypeId"]), Event.c_find(r["eventId"]))
LightResult.new(r)
}
end

Expand Down
10 changes: 5 additions & 5 deletions WcaOnRails/app/models/light_result.rb
Expand Up @@ -26,7 +26,7 @@ class LightResult
:regionalAverageRecord,
:country

def initialize(r, country, format, round_type, event)
def initialize(r)
@value1 = r["value1"]
@value2 = r["value2"]
@value3 = r["value3"]
Expand All @@ -39,10 +39,10 @@ def initialize(r, country, format, round_type, event)
@personId = r["personId"]
@regionalSingleRecord = r["regionalSingleRecord"]
@regionalAverageRecord = r["regionalAverageRecord"]
@country = country
@format = format
@round_type = round_type
@event = event
@country = Country.c_find(r["countryId"])
@format = Format.c_find(r["formatId"])
@round_type = RoundType.c_find(r["roundTypeId"])
@event = Event.c_find(r["eventId"])
end

def eventId
Expand Down