Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ruby '3.4.5'

gem 'mysql2', '~> 0.5.7'
gem 'sqlite3', '~> 1.4' # Alternative for development
gem 'puma', '~> 5.0'
gem 'puma', '~> 6.0'
gem 'rails', '~> 8.0', '>= 8.0.1'
gem 'mini_portile2', '~> 2.8' # Helps with native gem compilation
gem 'observer' # Required for Ruby 3.4.5 compatibility with Rails 8.0
Expand Down
36 changes: 33 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ GEM
term-ansicolor
thor
crass (1.0.6)
csv (3.3.5)
danger (9.5.3)
base64 (~> 0.2)
claide (~> 1.0)
Expand All @@ -128,6 +129,7 @@ GEM
debug (1.11.0)
irb (~> 1.10)
reline (>= 0.3.8)
delegate (0.4.0)
diff-lcs (1.6.2)
docile (1.4.1)
domain_name (0.6.20240107)
Expand All @@ -149,8 +151,11 @@ GEM
faraday (>= 0.8)
faraday-net_http (3.4.1)
net-http (>= 0.5.0)
faraday-retry (2.3.2)
faraday (~> 2.0)
find_with_order (1.3.1)
activerecord (>= 3)
forwardable (1.3.3)
git (2.3.3)
activesupport (>= 5.0)
addressable (~> 2.8)
Expand Down Expand Up @@ -197,10 +202,13 @@ GEM
mime-types-data (~> 3.2025, >= 3.2025.0507)
mime-types-data (3.2025.0924)
mini_mime (1.1.5)
mini_portile2 (2.8.9)
minitest (5.25.5)
mize (0.6.1)
monitor (0.2.0)
msgpack (1.8.0)
multi_json (1.17.0)
mutex_m (0.3.0)
mysql2 (0.5.7)
bigdecimal
nap (1.1.0)
Expand All @@ -217,7 +225,7 @@ GEM
net-protocol
netrc (0.11.0)
nio4r (2.5.9)
nokogiri (1.15.2-aarch64-linux)
nokogiri (1.18.10-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.10-arm64-darwin)
racc (~> 1.4)
Expand All @@ -230,6 +238,7 @@ GEM
faraday (>= 1, < 3)
sawyer (~> 0.9)
open4 (1.3.4)
ostruct (0.6.3)
parallel (1.27.0)
parser (3.3.9.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -350,6 +359,7 @@ GEM
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
securerandom (0.4.1)
set (1.1.2)
shoulda-matchers (6.5.0)
activesupport (>= 5.2.0)
simplecov (0.22.0)
Expand All @@ -358,7 +368,10 @@ GEM
simplecov_json_formatter (~> 0.1)
simplecov-html (0.13.2)
simplecov_json_formatter (0.1.4)
singleton (0.3.0)
spring (4.4.0)
sqlite3 (1.7.3)
mini_portile2 (~> 2.8.0)
stringio (3.1.7)
sync (0.5.0)
term-ansicolor (1.11.3)
Expand Down Expand Up @@ -398,18 +411,30 @@ PLATFORMS
DEPENDENCIES
active_model_serializers (~> 0.10.0)
bcrypt (~> 3.1.7)
bigdecimal
bootsnap (>= 1.18.4)
coveralls
csv
danger
database_cleaner-active_record
date
debug
delegate
factory_bot_rails
faker
faraday-retry
find_with_order
forwardable
jwt (~> 2.7, >= 2.7.1)
lingua
mysql2 (~> 0.5.5)
logger
mini_portile2 (~> 2.8)
monitor
mutex_m
mysql2 (~> 0.5.7)
observer
ostruct
psych (~> 5.2)
puma (~> 6.0)
rack-cors
rails (~> 8.0, >= 8.0.1)
Expand All @@ -418,14 +443,19 @@ DEPENDENCIES
rswag-specs
rswag-ui
rubocop
set
shoulda-matchers
simplecov
simplecov_json_formatter
singleton
spring
sqlite3 (~> 1.4)
timeout
tzinfo-data
uri

RUBY VERSION
ruby 3.2.7p253
ruby 3.4.5p51

BUNDLED WITH
2.4.14
29 changes: 29 additions & 0 deletions app/controllers/sign_up_topics_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,35 @@ def index
# render json: {message: 'All selected topics have been loaded successfully.', sign_up_topics: @stopics}, status: 200
end

def rubric_list
if params[:assignment_id].nil?
render json: { message: 'Assignment ID is required!' }, status: :unprocessable_entity
return
end

assignment = Assignment.find_by(id: params[:assignment_id])
if assignment.nil?
render json: { message: 'Assignment not found!' }, status: :not_found
return
end

topics = assignment.sign_up_topics.includes(:questionnaire)
render json: topics.map { |t| serialize_topic_with_rubric(t) }, status: :ok
end

private
def serialize_topic_with_rubric(topic)
{
id: topic.id,
name: topic.topic_name,
identifier: topic.topic_identifier,
max_choosers: topic.max_choosers,
questionnaire_id: topic.questionnaire_id,
questionnaire_name: topic.questionnaire&.name,
assignment_id: topic.assignment_id
}
end

# POST /sign_up_topics
# The create method allows the instructor to create a new topic
# params[:sign_up_topic][:topic_identifier] follows a json format
Expand Down
41 changes: 41 additions & 0 deletions app/helpers/topic_rubrics_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

module TopicRubricsHelper
# Assign a questionnaire to a specific topic
def self.assign_rubric_to_topic(topic_id, questionnaire_id, assignment_id, round = nil)
topic = SignUpTopic.find(topic_id)
assignment = Assignment.find(assignment_id)
questionnaire = Questionnaire.find(questionnaire_id)

# Validate that the questionnaire belongs to this assignment
unless assignment.questionnaires.include?(questionnaire)
raise ArgumentError, 'Questionnaire must be associated with this assignment'
end

# Check if assignment_questionnaire already exists
assignment_questionnaire = AssignmentQuestionnaire.find_or_initialize_by(
assignment_id: assignment_id,
questionnaire_id: questionnaire_id,
topic_id: topic_id,
used_in_round: round
)

assignment_questionnaire.save!
assignment_questionnaire
end

# Remove rubric assignment from a topic
def self.remove_rubric_from_topic(topic_id, assignment_id, round = nil)
AssignmentQuestionnaire.where(
assignment_id: assignment_id,
topic_id: topic_id,
used_in_round: round
).destroy_all
end

# Get the rubric for a topic (with fallback to default)
def self.get_rubric_for_topic(topic_id, round = nil)
topic = SignUpTopic.find(topic_id)
topic.rubric_for_review(round)
end
end
1 change: 1 addition & 0 deletions app/models/assignment_questionnaire.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
class AssignmentQuestionnaire < ApplicationRecord
belongs_to :assignment
belongs_to :questionnaire
belongs_to :topic, class_name: 'SignUpTopic', foreign_key: 'topic_id', optional: true
end
32 changes: 30 additions & 2 deletions app/models/sign_up_topic.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,37 @@
# frozen_string_literal: true

# frozen_string_literal: true

class SignUpTopic < ApplicationRecord
has_many :signed_up_teams, foreign_key: 'topic_id', dependent: :destroy
has_many :teams, through: :signed_up_teams # list all teams choose this topic, no matter in waitlist or not
has_many :teams, through: :signed_up_teams
has_many :assignment_questionnaires, class_name: 'AssignmentQuestionnaire', foreign_key: 'topic_id', dependent: :destroy
has_many :due_dates, as: :parent,class_name: 'DueDate', dependent: :destroy
has_many :due_dates, as: :parent, class_name: 'DueDate', dependent: :destroy
belongs_to :assignment
belongs_to :questionnaire, optional: true

# Get the rubric/questionnaire for this topic
# Falls back to the default assignment rubric if no topic-specific rubric exists
def rubric_for_review(round = nil)
# First, try to find a topic-specific rubric
topic_questionnaire = assignment_questionnaires.find_by(
assignment_id: assignment_id,
used_in_round: round
)&.questionnaire

return topic_questionnaire if topic_questionnaire.present?

# Fall back to the default assignment rubric
assignment.questionnaires.find_by(
assignment_questionnaires: { used_in_round: round }
)
end

# Check if this topic has a specific rubric assigned
def has_specific_rubric?(round = nil)
assignment_questionnaires.exists?(
assignment_id: assignment_id,
used_in_round: round
)
end
end
2 changes: 1 addition & 1 deletion config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def self.preview_path=(_)
module Reimplementation
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 7.0
config.load_defaults 8.0
config.active_record.schema_format = :ruby

# Configuration for the application, engines, and railties goes here.
Expand Down
12 changes: 9 additions & 3 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,16 @@
end
end



resources :sign_up_topics do
resources :sign_up_topics, only: [:index, :create, :update, :show, :destroy] do
member do
post :assign_rubric
delete :remove_rubric
get :show_rubric
end
collection do
get :filter
delete '/', to: 'sign_up_topics#destroy'
get :rubric_list
end
end

Expand Down Expand Up @@ -141,4 +145,6 @@
delete :delete_participants
end
end


end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddTopicIdToAssignmentQuestionnaires < ActiveRecord::Migration[8.0]
def change
add_column :assignment_questionnaires, :topic_id, :bigint
add_index :assignment_questionnaires, :topic_id
add_foreign_key :assignment_questionnaires, :sign_up_topics, column: :topic_id
end
end
5 changes: 4 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
command: tail -f /dev/null
environment:
RAILS_ENV: development
DATABASE_URL: mysql2://root:expertiza@db:3306/reimplementation?
DATABASE_URL: mysql2://root:expertiza@db:3306/reimplementation
CACHE_STORE: redis://redis:6380/0
ports:
- "3002:3002"
Expand All @@ -24,7 +24,7 @@ services:
ports:
- "3307:3306"
volumes:
- expertiza-mysql:/var/lib/mysql2/data
- expertiza-mysql:/var/lib/mysql
- ./db:/docker-entrypoint-initdb.d

redis:
Expand Down
Loading