
We want to differentiate between those RfCs explicitly marked as solved, those potentially solved since the author reached the maximum score, and those being unsolved where the author has not yet reached the full score yet.
124 lines
3.9 KiB
Ruby
124 lines
3.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class RequestForComment < ApplicationRecord
|
|
include Creation
|
|
include ActionCableHelper
|
|
|
|
# SOLVED: The author explicitly marked the RfC as solved.
|
|
# SOFT_SOLVED: The author did not mark the RfC as solved but reached the maximum score in the corresponding exercise at any time.
|
|
# ONGOING: The author did not mark the RfC as solved and did not reach the maximum score in the corresponding exercise yet.
|
|
# ALL: Any RfC, regardless of the author marking it as solved or reaching the maximum score in the corresponding exercise.
|
|
STATE = [SOLVED = :solved, SOFT_SOLVED = :soft_solved, ONGOING = :unsolved, ALL = :all].freeze
|
|
|
|
belongs_to :submission
|
|
belongs_to :exercise
|
|
belongs_to :file, class_name: 'CodeOcean::File'
|
|
|
|
has_many :comments, through: :submission
|
|
has_many :subscriptions, dependent: :destroy
|
|
|
|
scope :unsolved, -> { where(solved: [false, nil]) }
|
|
scope :in_range, ->(from, to) { from == DateTime.new(0) && to > 5.seconds.ago ? all : where(created_at: from..to) }
|
|
scope :with_comments, -> { select {|rfc| rfc.comments.any? } }
|
|
|
|
# after_save :trigger_rfc_action_cable
|
|
|
|
def commenters
|
|
comments.map(&:user).uniq
|
|
end
|
|
|
|
def comments?
|
|
comments.any?
|
|
end
|
|
|
|
def to_s
|
|
"RFC-#{id}"
|
|
end
|
|
|
|
def current_state
|
|
state(solved, full_score_reached)
|
|
end
|
|
|
|
def old_state
|
|
state(solved_before_last_save, full_score_reached_before_last_save)
|
|
end
|
|
|
|
def self.parent_resource
|
|
Exercise
|
|
end
|
|
|
|
private
|
|
|
|
def state(solved, full_score_reached)
|
|
if solved
|
|
SOLVED
|
|
elsif full_score_reached
|
|
SOFT_SOLVED
|
|
else
|
|
ONGOING
|
|
end
|
|
end
|
|
|
|
class << self
|
|
def state(filter = RequestForComment::ALL)
|
|
# This method is used as a scope filter for Ransack
|
|
|
|
case filter.to_sym
|
|
when RequestForComment::SOLVED
|
|
where(solved: true)
|
|
when RequestForComment::SOFT_SOLVED
|
|
unsolved.where(full_score_reached: true)
|
|
when RequestForComment::ONGOING
|
|
unsolved.where(full_score_reached: false)
|
|
else # 'all'
|
|
all
|
|
end
|
|
end
|
|
|
|
def with_last_activity
|
|
joins('join "submissions" s on s.id = request_for_comments.submission_id ' \
|
|
'left outer join "files" f on f.context_id = s.id ' \
|
|
'left outer join "comments" c on c.file_id = f.id')
|
|
.group('request_for_comments.id')
|
|
.select('request_for_comments.*, max(c.updated_at) as last_comment')
|
|
end
|
|
|
|
def last_per_user(count = 5)
|
|
from(row_number_user_sql, :request_for_comments)
|
|
.where('row_number <= ?', count)
|
|
.group('request_for_comments.id, request_for_comments.user_id, request_for_comments.user_type, ' \
|
|
'request_for_comments.exercise_id, request_for_comments.file_id, request_for_comments.question, ' \
|
|
'request_for_comments.created_at, request_for_comments.updated_at, request_for_comments.solved, ' \
|
|
'request_for_comments.full_score_reached, request_for_comments.submission_id, request_for_comments.row_number')
|
|
# ugly, but necessary
|
|
end
|
|
|
|
def ransackable_associations(_auth_object = nil)
|
|
%w[exercise submission]
|
|
end
|
|
|
|
def ransackable_scopes(_auth_object = nil)
|
|
%w[state]
|
|
end
|
|
|
|
private
|
|
|
|
def row_number_user_sql
|
|
select('
|
|
request_for_comments.id,
|
|
request_for_comments.user_id,
|
|
request_for_comments.user_type,
|
|
request_for_comments.exercise_id,
|
|
request_for_comments.file_id,
|
|
request_for_comments.question,
|
|
request_for_comments.created_at,
|
|
request_for_comments.updated_at,
|
|
request_for_comments.solved,
|
|
request_for_comments.full_score_reached,
|
|
request_for_comments.submission_id,
|
|
row_number() OVER (PARTITION BY request_for_comments.user_id, request_for_comments.user_type ORDER BY request_for_comments.created_at DESC) as row_number
|
|
')
|
|
end
|
|
end
|
|
end
|