RfCs: Allow filtering for any states

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.
This commit is contained in:
Sebastian Serth
2024-04-18 10:00:19 +02:00
committed by Dominic Sauer
parent d72139cf04
commit 7cc4fb00c6
6 changed files with 51 additions and 8 deletions

View File

@ -33,4 +33,8 @@ class ApplicationRecord < ActiveRecord::Base
def self.ransackable_attributes(_auth_object = nil) def self.ransackable_attributes(_auth_object = nil)
[] []
end end
def self.ransackable_scopes(_auth_object = nil)
[]
end
end end

View File

@ -7,7 +7,8 @@ class RequestForComment < ApplicationRecord
# SOLVED: The author explicitly marked the RfC as solved. # 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. # 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. # ONGOING: The author did not mark the RfC as solved and did not reach the maximum score in the corresponding exercise yet.
STATE = [SOLVED = :solved, SOFT_SOLVED = :soft_solved, ONGOING = :unsolved].freeze # 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 :submission
belongs_to :exercise belongs_to :exercise
@ -59,6 +60,21 @@ class RequestForComment < ApplicationRecord
end end
class << self 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 def with_last_activity
joins('join "submissions" s on s.id = request_for_comments.submission_id ' \ 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 "files" f on f.context_id = s.id ' \
@ -81,8 +97,8 @@ class RequestForComment < ApplicationRecord
%w[exercise submission] %w[exercise submission]
end end
def ransackable_attributes(_auth_object = nil) def ransackable_scopes(_auth_object = nil)
%w[solved] %w[state]
end end
private private

View File

@ -9,7 +9,7 @@ h1 = RequestForComment.model_name.human(count: 2)
= f.search_field(:exercise_title_cont, class: 'form-control', placeholder: t('activerecord.attributes.request_for_comments.exercise')) = f.search_field(:exercise_title_cont, class: 'form-control', placeholder: t('activerecord.attributes.request_for_comments.exercise'))
.col-auto.mt-3.mt-md-0 .col-auto.mt-3.mt-md-0
= f.label(:title_cont, t('request_for_comments.solved'), class: 'visually-hidden form-label') = f.label(:title_cont, t('request_for_comments.solved'), class: 'visually-hidden form-label')
= f.select(:solved_not_eq, [[t('request_for_comments.show_all'), 2], [t('request_for_comments.show_unsolved'), 1], [t('request_for_comments.show_solved'), 0]]) = f.select(:state, [[t('request_for_comments.show_all'), RequestForComment::ALL], [t('request_for_comments.show_unsolved'), RequestForComment::ONGOING], [t('request_for_comments.show_soft_solved'), RequestForComment::SOFT_SOLVED], [t('request_for_comments.show_solved'), RequestForComment::SOLVED]])
- unless current_user.consumer.rfc_visibility_study_group? - unless current_user.consumer.rfc_visibility_study_group?
.row .row
.col .col

View File

@ -857,6 +857,7 @@ de:
mark_as_solved: "Diese Frage als beantwortet markieren" mark_as_solved: "Diese Frage als beantwortet markieren"
show_all: "Alle Anfragen anzeigen" show_all: "Alle Anfragen anzeigen"
show_solved: "Nur gelöste Anfragen anzeigen" show_solved: "Nur gelöste Anfragen anzeigen"
show_soft_solved: "Nur potenziell gelöste Anfragen anzeigen"
show_unsolved: "Nur ungelöste Anfragen anzeigen" show_unsolved: "Nur ungelöste Anfragen anzeigen"
solved: "Diese Frage wurde erfolgreich beantwortet" solved: "Diese Frage wurde erfolgreich beantwortet"
comment_exercise: "Ich möchte die Aufgabenstellung kommentieren" comment_exercise: "Ich möchte die Aufgabenstellung kommentieren"

View File

@ -856,8 +856,9 @@ en:
no_question: "The author did not enter a question for this request." no_question: "The author did not enter a question for this request."
mark_as_solved: "Mark this question as answered" mark_as_solved: "Mark this question as answered"
show_all: "All requests" show_all: "All requests"
show_solved: "Solved requests" show_solved: "Show only solved requests"
show_unsolved: "Unvsolved requests" show_soft_solved: "Show only requests presumably solved"
show_unsolved: "Show only unsolved requests"
solved: "This question has been answered" solved: "This question has been answered"
comment_exercise: "I would like to give feedback for this exercise" comment_exercise: "I would like to give feedback for this exercise"
write_a_thank_you_node: "If you want, you can write a thank you note to all your commenters:" write_a_thank_you_node: "If you want, you can write a thank you note to all your commenters:"

View File

@ -3,9 +3,8 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe RequestForComment do RSpec.describe RequestForComment do
let!(:rfc) { create(:rfc) }
describe 'scope with_comments' do describe 'scope with_comments' do
let!(:rfc) { create(:rfc) }
let!(:rfc2) { create(:rfc_with_comment) } let!(:rfc2) { create(:rfc_with_comment) }
it 'includes all RfCs with comments' do it 'includes all RfCs with comments' do
@ -16,4 +15,26 @@ RSpec.describe RequestForComment do
expect(described_class.with_comments).not_to include(rfc) expect(described_class.with_comments).not_to include(rfc)
end end
end end
describe 'state' do
let!(:rfc_solved) { create(:rfc, solved: true) }
let!(:rfc_soft_solved) { create(:rfc, solved: false, full_score_reached: true) }
let!(:rfc_ongoing) { create(:rfc, solved: false, full_score_reached: false) }
it 'returns solved RfCs when solved state is requested' do
expect(described_class.state(RequestForComment::SOLVED)).to contain_exactly(rfc_solved)
end
it 'returns soft solved RfCs when soft solved state is requested' do
expect(described_class.state(RequestForComment::SOFT_SOLVED)).to contain_exactly(rfc_soft_solved)
end
it 'returns ongoing RfCs when ongoing state is requested' do
expect(described_class.state(RequestForComment::ONGOING)).to contain_exactly(rfc_ongoing)
end
it 'returns all RfCs when all state is requested' do
expect(described_class.state(RequestForComment::ALL)).to contain_exactly(rfc_solved, rfc_soft_solved, rfc_ongoing)
end
end
end end