diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -57,8 +57,12 @@ @prob_submissions = Array.new @user = User.find(session[:user_id]) @problems.each do |p| - c, sub = Submission.find_by_user_and_problem(@user.id,p.id) - @prob_submissions << { :count => c, :submission => sub } + sub = Submission.find_last_by_user_and_problem(@user.id,p.id) + if sub!=nil + @prob_submissions << { :count => sub.number, :submission => sub } + else + @prob_submissions << { :count => 0, :submission => nil } + end end end diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb --- a/app/controllers/problems_controller.rb +++ b/app/controllers/problems_controller.rb @@ -65,6 +65,6 @@ def stat @problem = Problem.find(params[:id]) - @submissions = Submission.find_last_by_problem(params[:id]) + @submissions = Submission.find_all_last_by_problem(params[:id]) end end diff --git a/app/controllers/user_admin_controller.rb b/app/controllers/user_admin_controller.rb --- a/app/controllers/user_admin_controller.rb +++ b/app/controllers/user_admin_controller.rb @@ -77,8 +77,8 @@ ustat = Array.new ustat[0] = u.login @problems.each do |p| - c, sub = Submission.find_by_user_and_problem(u.id,p.id) - if (c!=0) and (sub.points!=nil) + sub = Submission.find_last_by_user_and_problem(u.id,p.id) + if (sub!=nil) and (sub.points!=nil) ustat << [sub.points, (sub.points>=p.full_score)] else ustat << [0,false] diff --git a/app/models/submission.rb b/app/models/submission.rb --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -10,20 +10,17 @@ validate :must_specify_language validate :must_have_valid_problem - def self.find_by_user_and_problem(user_id, problem_id) - subcount = count(:conditions => "user_id = #{user_id} AND problem_id = #{problem_id}") - if subcount != 0 - last_sub = find(:first, - :conditions => {:user_id => user_id, - :problem_id => problem_id}, - :order => 'submitted_at DESC') - else - last_sub = nil - end - return subcount, last_sub + before_save :assign_latest_number + + def self.find_last_by_user_and_problem(user_id, problem_id) + last_sub = find(:first, + :conditions => {:user_id => user_id, + :problem_id => problem_id}, + :order => 'submitted_at DESC') + return last_sub end - def self.find_last_by_problem(problem_id) + def self.find_all_last_by_problem(problem_id) # need to put in SQL command, maybe there's a better way Submission.find_by_sql("SELECT * FROM submissions " + "WHERE id = " + @@ -33,6 +30,8 @@ "GROUP BY user_id)") end + protected + def self.find_option_in_source(option, source) if source==nil return nil @@ -92,4 +91,10 @@ end end + # callbacks + def assign_latest_number + latest = Submission.find_last_by_user_and_problem(self.user_id, self.problem_id) + self.number = (latest==nil) ? 1 : latest.number + 1; + end + end diff --git a/db/migrate/018_add_number_to_submissions.rb b/db/migrate/018_add_number_to_submissions.rb new file mode 100644 --- /dev/null +++ b/db/migrate/018_add_number_to_submissions.rb @@ -0,0 +1,33 @@ +class AddNumberToSubmissions < ActiveRecord::Migration + def self.up + add_column :submissions, :number, :integer + + # add number field for all records + Submission.reset_column_information + + last_user_id = nil + last_problem_id = nil + current_number = 0 + + Submission.find(:all, + :order => 'user_id, problem_id, submitted_at').each do |submission| + if submission.user_id==last_user_id and submission.problem_id==last_problem_id + current_number += 1 + else + current_number = 1 + end + submission.number = current_number + submission.save + + last_user_id = submission.user_id + last_problem_id = submission.problem_id + end + + add_index :submissions, [:user_id, :problem_id, :number], :unique => true + end + + def self.down + remove_index :submissions, :column => [:user_id, :problem_id, :number] + remove_column :submissions, :number + end +end diff --git a/db/schema.rb b/db/schema.rb --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 17) do +ActiveRecord::Schema.define(:version => 18) do create_table "grader_processes", :force => true do |t| t.string "host", :limit => 20 @@ -83,8 +83,10 @@ t.datetime "graded_at" t.integer "points" t.text "grader_comment" + t.integer "number" end + add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id" create_table "tasks", :force => true do |t|