Fix missing/incorrect Model specifications in migrations

We need to define the required models within the migration (not below) to work reliably.
This commit is contained in:
Sebastian Serth
2024-07-01 23:29:15 +02:00
committed by Sebastian Serth
parent cef961a1e7
commit 6c44ffbd5c
20 changed files with 211 additions and 39 deletions

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class SorceryCore < ActiveRecord::Migration[4.2]
class InternalUser < ApplicationRecord
end
def change
InternalUser.delete_all
add_column :internal_users, :crypted_password, :string, null: false

View File

@ -1,6 +1,20 @@
# frozen_string_literal: true
class AddHashedContentToFiles < ActiveRecord::Migration[4.2]
class CodeOcean::File < ApplicationRecord
before_validation :hash_content, if: :content_present?
private
def content_present?
content? || native_file?
end
def hash_content
self.hashed_content = Digest::MD5.new.hexdigest(read || '')
end
end
def change
add_column :files, :hashed_content, :string

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class AddPoolSizeToExecutionEnvironments < ActiveRecord::Migration[4.2]
class ExecutionEnvironment < ApplicationRecord
end
def change
add_column :execution_environments, :pool_size, :integer

View File

@ -1,6 +1,10 @@
# frozen_string_literal: true
class AddMemoryLimitToExecutionEnvironments < ActiveRecord::Migration[4.2]
class ExecutionEnvironment < ApplicationRecord
DEFAULT_MEMORY_LIMIT = 256
end
def change
add_column :execution_environments, :memory_limit, :integer

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class AddNetworkEnabledToExecutionEnvironments < ActiveRecord::Migration[4.2]
class ExecutionEnvironment < ApplicationRecord
end
def change
add_column :execution_environments, :network_enabled, :boolean

View File

@ -3,31 +3,32 @@
class AddSubmissionToRequestForComments < ActiveRecord::Migration[4.2]
def change
add_reference :request_for_comments, :submission
end
end
# We issued the following on the database to add the submission_ids for existing entries
#
# UPDATE request_for_comments
# SET submission_id = sub.submission_id_external
# FROM
# (SELECT s.id AS submission_id_external,
# rfc.id AS rfc_id,
# s.created_at AS submission_created_at,
# rfc.created_at AS rfc_created_at
# FROM submissions s,
# request_for_comments rfc
# WHERE s.user_id = rfc.user_id
# AND s.exercise_id = rfc.exercise_id
# AND rfc.created_at + interval '2 hours' > s.created_at
# AND s.created_at =
# (SELECT MAX(created_at)
# FROM submissions
# WHERE exercise_id = s.exercise_id
# AND user_id = s.user_id
# AND rfc.created_at + interval '2 hours' > created_at
# GROUP BY s.exercise_id,
# s.user_id)) as sub
# WHERE id = sub.rfc_id
# AND submission_id IS NULL;
#
up_only do
execute <<-SQL.squish
UPDATE request_for_comments
SET submission_id = sub.submission_id_external
FROM
(SELECT s.id AS submission_id_external,
rfc.id AS rfc_id,
s.created_at AS submission_created_at,
rfc.created_at AS rfc_crea
FROM submissions s,
request_for_comments rfc
WHERE s.user_id = rfc.user_id
AND s.exercise_id = rfc.exercise_id
AND rfc.created_at + interval '2 hours' > s.created_at
AND s.created_at =
(SELECT MAX(created_at)
FROM submissions
WHERE exercise_id = s.exercise_id
AND user_id = s.user_id
AND rfc.created_at + interval '2 hours' > created_at
GROUP BY s.exercise_id,
s.user_id)) as sub
WHERE id = sub.rfc_id
AND submission_id IS NULL;
SQL
end
end
end

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class SetDefaultForRequestForCommentSolved < ActiveRecord::Migration[4.2]
class RequestForComment < ApplicationRecord
end
def change
change_column_default :request_for_comments, :solved, false
RequestForComment.where(solved: nil).update(solved: false)

View File

@ -1,6 +1,13 @@
# frozen_string_literal: true
class AddCauseToTestruns < ActiveRecord::Migration[4.2]
class Testrun < ApplicationRecord
belongs_to :submission, optional: true
end
class Submission < ApplicationRecord
end
def up
add_column :testruns, :cause, :string
Testrun.reset_column_information

View File

@ -1,6 +1,57 @@
# frozen_string_literal: true
class AddReachedFullScoreToRequestForComment < ActiveRecord::Migration[4.2]
class RequestForComment < ApplicationRecord
belongs_to :submission, optional: true
belongs_to :user, optional: true
end
class Submission < ApplicationRecord
belongs_to :exercise
belongs_to :user, polymorphic: true
end
class Exercise < ApplicationRecord
has_many :files, as: :context, class_name: 'CodeOcean::File'
has_many :submissions
def solved_by?(user)
maximum_score(user).to_i == maximum_score.to_i
end
def maximum_score(user)
if user
submissions
.where(user:, cause: %w[submit assess])
.where.not(score: nil)
.order(score: :desc)
.first&.score || 0
else
@maximum_score ||= if files.loaded?
files.filter(&:teacher_defined_assessment?).pluck(:weight).sum
else
files.teacher_defined_assessments.sum(:weight)
end
end
end
end
class CodeOcean::File < ApplicationRecord
belongs_to :context, polymorphic: true
scope :teacher_defined_assessments, -> { where(role: %w[teacher_defined_test teacher_defined_linter]) }
ROLES = %w[regular_file main_file reference_implementation executable_file teacher_defined_test user_defined_file
user_defined_test teacher_defined_linter].freeze
def teacher_defined_assessment?
teacher_defined_test? || teacher_defined_linter?
end
ROLES.each do |role|
define_method(:"#{role}?") { self.role == role }
end
end
def up
add_column :request_for_comments, :full_score_reached, :boolean, default: false
RequestForComment.find_each do |rfc|

View File

@ -1,6 +1,13 @@
# frozen_string_literal: true
class AddUserToProxyExercise < ActiveRecord::Migration[5.2]
class Internaluser < ApplicationRecord
end
class ProxyExercise < ApplicationRecord
belongs_to :user, polymorphic: true
end
def change
add_reference :proxy_exercises, :user, polymorphic: true, index: true
add_column :proxy_exercises, :public, :boolean, null: false, default: false

View File

@ -1,6 +1,10 @@
# frozen_string_literal: true
class AddUserTypeToRemoteEvaluationMappings < ActiveRecord::Migration[5.2]
class RemoteEvaluationMapping < ApplicationRecord
belongs_to :user, polymorphic: true
end
def change
add_column :remote_evaluation_mappings, :user_type, :string
# Update all existing records and set user_type to `ExternalUser` (safe way to prevent any function loss).

View File

@ -1,6 +1,18 @@
# frozen_string_literal: true
class AddNormalizedScoreAndSubmissionToUserExerciseFeedback < ActiveRecord::Migration[5.2]
class UserExerciseFeedback < ApplicationRecord
belongs_to :submission
belongs_to :exercise
end
class Submission < ApplicationRecord
belongs_to :user, polymorphic: true
end
class Exercise < ApplicationRecord
end
def change
add_column :user_exercise_feedbacks, :normalized_score, :float
add_reference :user_exercise_feedbacks, :submission, foreign_key: true
@ -9,7 +21,7 @@ class AddNormalizedScoreAndSubmissionToUserExerciseFeedback < ActiveRecord::Migr
ActiveRecord::Base.record_timestamps = false
UserExerciseFeedback.find_each do |uef|
latest_submission = Submission
.where(user_id: uef.user_id, user_type: uef.user_type, exercise_id: uef.exercise_id)
.where(user: uef.user, exercise: uef.exercise)
.where(created_at: ...uef.updated_at)
.order(created_at: :desc).first

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class ChangeTypeOfExposedPortsInExecutionEnvironment < ActiveRecord::Migration[6.1]
class ExecutionEnvironment < ApplicationRecord
end
# rubocop:disable Rails/SkipsModelValidations:
def up
rename_column :execution_environments, :exposed_ports, :exposed_ports_migration

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class CreateTipsIntervention < ActiveRecord::Migration[6.1]
class Intervention < ApplicationRecord
end
def change
Intervention.find_or_create_by(name: 'TipsIntervention')
end

View File

@ -1,6 +1,19 @@
# frozen_string_literal: true
class MigrateTestruns < ActiveRecord::Migration[6.1]
class Testrun < ApplicationRecord
belongs_to :submission, optional: true
has_many :testrun_messages
end
class Submission < ApplicationRecord
has_many :testruns
end
class TestrunMessage < ApplicationRecord
belongs_to :testrun
end
# We are not changing any tables but only backfilling data.
disable_ddl_transaction!

View File

@ -1,6 +1,32 @@
# frozen_string_literal: true
class MigratePermissionsToStudyGroup < ActiveRecord::Migration[6.1]
class Consumer < ApplicationRecord
has_many :study_groups
has_many :internal_users
has_many :external_users
end
class StudyGroup < ApplicationRecord
belongs_to :consumer
has_many :study_group_memberships
end
class InternalUser < ApplicationRecord
belongs_to :consumer
has_many :study_group_memberships, as: :user
end
class ExternalUser < ApplicationRecord
belongs_to :consumer
has_many :study_group_memberships, as: :user
end
class StudyGroupMembership < ApplicationRecord
belongs_to :study_group
belongs_to :user, polymorphic: true
end
# rubocop:disable Rails/SkipsModelValidations
def up
create_default_groups

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class MigrateFiletypeExtensionsNotNil < ActiveRecord::Migration[7.0]
class FileType < ApplicationRecord
end
def change
FileType.all.find_all {|file_type| file_type.file_extension.nil? }.each do |file_type|
file_type.update file_extension: ''

View File

@ -1,6 +1,19 @@
# frozen_string_literal: true
class UnifyLtiParameters < ActiveRecord::Migration[7.0]
class LtiParameter < ApplicationRecord
belongs_to :external_user
belongs_to :exercise
end
class ExternalUser < ApplicationRecord
has_many :lti_parameters
end
class Exercise < ApplicationRecord
has_many :lti_parameters
end
def change
reversible do |dir|
dir.up do
@ -35,10 +48,4 @@ class UnifyLtiParameters < ActiveRecord::Migration[7.0]
add_index :lti_parameters, %i[external_user_id study_group_id exercise_id], unique: true, name: 'index_lti_params_on_external_user_and_study_group_and_exercise'
end
class LtiParameter < ActiveRecord::Base; end
class ExternalUser < ActiveRecord::Base; end
class Exercise < ActiveRecord::Base; end
end

View File

@ -1,6 +1,14 @@
# frozen_string_literal: true
class AddForeignKeysToAnomalyNotifications < ActiveRecord::Migration[7.0]
class AnomalyNotification < ApplicationRecord
belongs_to :exercise
end
class Exercise < ApplicationRecord
has_many :anomaly_notifications
end
def change
up_only do
# We cannot add a foreign key to a table that has rows that violate the constraint.
@ -16,8 +24,4 @@ class AddForeignKeysToAnomalyNotifications < ActiveRecord::Migration[7.0]
change_column_null :anomaly_notifications, :exercise_collection_id, false
add_foreign_key :anomaly_notifications, :exercise_collections
end
class AnomalyNotification < ActiveRecord::Base; end
class Exercise < ActiveRecord::Base; end
class ExerciseCollection < ActiveRecord::Base; end
end

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class ConvertReasonToJsonInAnomalyNotifications < ActiveRecord::Migration[7.0]
class AnomalyNotification < ApplicationRecord
end
def up
AnomalyNotification.where("reason LIKE '%value:%'").find_each do |anomaly_notification|
reason = anomaly_notification.reason
@ -14,6 +17,4 @@ class ConvertReasonToJsonInAnomalyNotifications < ActiveRecord::Migration[7.0]
def down
change_column :anomaly_notifications, :reason, :string
end
class AnomalyNotification < ActiveRecord::Base; end
end