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:

committed by
Sebastian Serth

parent
cef961a1e7
commit
6c44ffbd5c
@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SorceryCore < ActiveRecord::Migration[4.2]
|
class SorceryCore < ActiveRecord::Migration[4.2]
|
||||||
|
class InternalUser < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
InternalUser.delete_all
|
InternalUser.delete_all
|
||||||
add_column :internal_users, :crypted_password, :string, null: false
|
add_column :internal_users, :crypted_password, :string, null: false
|
||||||
|
@ -1,6 +1,20 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddHashedContentToFiles < ActiveRecord::Migration[4.2]
|
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
|
def change
|
||||||
add_column :files, :hashed_content, :string
|
add_column :files, :hashed_content, :string
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddPoolSizeToExecutionEnvironments < ActiveRecord::Migration[4.2]
|
class AddPoolSizeToExecutionEnvironments < ActiveRecord::Migration[4.2]
|
||||||
|
class ExecutionEnvironment < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
add_column :execution_environments, :pool_size, :integer
|
add_column :execution_environments, :pool_size, :integer
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddMemoryLimitToExecutionEnvironments < ActiveRecord::Migration[4.2]
|
class AddMemoryLimitToExecutionEnvironments < ActiveRecord::Migration[4.2]
|
||||||
|
class ExecutionEnvironment < ApplicationRecord
|
||||||
|
DEFAULT_MEMORY_LIMIT = 256
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
add_column :execution_environments, :memory_limit, :integer
|
add_column :execution_environments, :memory_limit, :integer
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddNetworkEnabledToExecutionEnvironments < ActiveRecord::Migration[4.2]
|
class AddNetworkEnabledToExecutionEnvironments < ActiveRecord::Migration[4.2]
|
||||||
|
class ExecutionEnvironment < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
add_column :execution_environments, :network_enabled, :boolean
|
add_column :execution_environments, :network_enabled, :boolean
|
||||||
|
|
||||||
|
@ -3,31 +3,32 @@
|
|||||||
class AddSubmissionToRequestForComments < ActiveRecord::Migration[4.2]
|
class AddSubmissionToRequestForComments < ActiveRecord::Migration[4.2]
|
||||||
def change
|
def change
|
||||||
add_reference :request_for_comments, :submission
|
add_reference :request_for_comments, :submission
|
||||||
|
|
||||||
|
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
|
||||||
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;
|
|
||||||
#
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SetDefaultForRequestForCommentSolved < ActiveRecord::Migration[4.2]
|
class SetDefaultForRequestForCommentSolved < ActiveRecord::Migration[4.2]
|
||||||
|
class RequestForComment < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
change_column_default :request_for_comments, :solved, false
|
change_column_default :request_for_comments, :solved, false
|
||||||
RequestForComment.where(solved: nil).update(solved: false)
|
RequestForComment.where(solved: nil).update(solved: false)
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddCauseToTestruns < ActiveRecord::Migration[4.2]
|
class AddCauseToTestruns < ActiveRecord::Migration[4.2]
|
||||||
|
class Testrun < ApplicationRecord
|
||||||
|
belongs_to :submission, optional: true
|
||||||
|
end
|
||||||
|
|
||||||
|
class Submission < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
def up
|
def up
|
||||||
add_column :testruns, :cause, :string
|
add_column :testruns, :cause, :string
|
||||||
Testrun.reset_column_information
|
Testrun.reset_column_information
|
||||||
|
@ -1,6 +1,57 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddReachedFullScoreToRequestForComment < ActiveRecord::Migration[4.2]
|
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
|
def up
|
||||||
add_column :request_for_comments, :full_score_reached, :boolean, default: false
|
add_column :request_for_comments, :full_score_reached, :boolean, default: false
|
||||||
RequestForComment.find_each do |rfc|
|
RequestForComment.find_each do |rfc|
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddUserToProxyExercise < ActiveRecord::Migration[5.2]
|
class AddUserToProxyExercise < ActiveRecord::Migration[5.2]
|
||||||
|
class Internaluser < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
|
class ProxyExercise < ApplicationRecord
|
||||||
|
belongs_to :user, polymorphic: true
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
add_reference :proxy_exercises, :user, polymorphic: true, index: true
|
add_reference :proxy_exercises, :user, polymorphic: true, index: true
|
||||||
add_column :proxy_exercises, :public, :boolean, null: false, default: false
|
add_column :proxy_exercises, :public, :boolean, null: false, default: false
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddUserTypeToRemoteEvaluationMappings < ActiveRecord::Migration[5.2]
|
class AddUserTypeToRemoteEvaluationMappings < ActiveRecord::Migration[5.2]
|
||||||
|
class RemoteEvaluationMapping < ApplicationRecord
|
||||||
|
belongs_to :user, polymorphic: true
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
add_column :remote_evaluation_mappings, :user_type, :string
|
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).
|
# Update all existing records and set user_type to `ExternalUser` (safe way to prevent any function loss).
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddNormalizedScoreAndSubmissionToUserExerciseFeedback < ActiveRecord::Migration[5.2]
|
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
|
def change
|
||||||
add_column :user_exercise_feedbacks, :normalized_score, :float
|
add_column :user_exercise_feedbacks, :normalized_score, :float
|
||||||
add_reference :user_exercise_feedbacks, :submission, foreign_key: true
|
add_reference :user_exercise_feedbacks, :submission, foreign_key: true
|
||||||
@ -9,7 +21,7 @@ class AddNormalizedScoreAndSubmissionToUserExerciseFeedback < ActiveRecord::Migr
|
|||||||
ActiveRecord::Base.record_timestamps = false
|
ActiveRecord::Base.record_timestamps = false
|
||||||
UserExerciseFeedback.find_each do |uef|
|
UserExerciseFeedback.find_each do |uef|
|
||||||
latest_submission = Submission
|
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)
|
.where(created_at: ...uef.updated_at)
|
||||||
.order(created_at: :desc).first
|
.order(created_at: :desc).first
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ChangeTypeOfExposedPortsInExecutionEnvironment < ActiveRecord::Migration[6.1]
|
class ChangeTypeOfExposedPortsInExecutionEnvironment < ActiveRecord::Migration[6.1]
|
||||||
|
class ExecutionEnvironment < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
# rubocop:disable Rails/SkipsModelValidations:
|
# rubocop:disable Rails/SkipsModelValidations:
|
||||||
def up
|
def up
|
||||||
rename_column :execution_environments, :exposed_ports, :exposed_ports_migration
|
rename_column :execution_environments, :exposed_ports, :exposed_ports_migration
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class CreateTipsIntervention < ActiveRecord::Migration[6.1]
|
class CreateTipsIntervention < ActiveRecord::Migration[6.1]
|
||||||
|
class Intervention < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
Intervention.find_or_create_by(name: 'TipsIntervention')
|
Intervention.find_or_create_by(name: 'TipsIntervention')
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,19 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MigrateTestruns < ActiveRecord::Migration[6.1]
|
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.
|
# We are not changing any tables but only backfilling data.
|
||||||
disable_ddl_transaction!
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
@ -1,6 +1,32 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MigratePermissionsToStudyGroup < ActiveRecord::Migration[6.1]
|
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
|
# rubocop:disable Rails/SkipsModelValidations
|
||||||
def up
|
def up
|
||||||
create_default_groups
|
create_default_groups
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MigrateFiletypeExtensionsNotNil < ActiveRecord::Migration[7.0]
|
class MigrateFiletypeExtensionsNotNil < ActiveRecord::Migration[7.0]
|
||||||
|
class FileType < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
FileType.all.find_all {|file_type| file_type.file_extension.nil? }.each do |file_type|
|
FileType.all.find_all {|file_type| file_type.file_extension.nil? }.each do |file_type|
|
||||||
file_type.update file_extension: ''
|
file_type.update file_extension: ''
|
||||||
|
@ -1,6 +1,19 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class UnifyLtiParameters < ActiveRecord::Migration[7.0]
|
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
|
def change
|
||||||
reversible do |dir|
|
reversible do |dir|
|
||||||
dir.up do
|
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'
|
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
|
end
|
||||||
|
|
||||||
class LtiParameter < ActiveRecord::Base; end
|
|
||||||
|
|
||||||
class ExternalUser < ActiveRecord::Base; end
|
|
||||||
|
|
||||||
class Exercise < ActiveRecord::Base; end
|
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddForeignKeysToAnomalyNotifications < ActiveRecord::Migration[7.0]
|
class AddForeignKeysToAnomalyNotifications < ActiveRecord::Migration[7.0]
|
||||||
|
class AnomalyNotification < ApplicationRecord
|
||||||
|
belongs_to :exercise
|
||||||
|
end
|
||||||
|
|
||||||
|
class Exercise < ApplicationRecord
|
||||||
|
has_many :anomaly_notifications
|
||||||
|
end
|
||||||
|
|
||||||
def change
|
def change
|
||||||
up_only do
|
up_only do
|
||||||
# We cannot add a foreign key to a table that has rows that violate the constraint.
|
# 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
|
change_column_null :anomaly_notifications, :exercise_collection_id, false
|
||||||
add_foreign_key :anomaly_notifications, :exercise_collections
|
add_foreign_key :anomaly_notifications, :exercise_collections
|
||||||
end
|
end
|
||||||
|
|
||||||
class AnomalyNotification < ActiveRecord::Base; end
|
|
||||||
class Exercise < ActiveRecord::Base; end
|
|
||||||
class ExerciseCollection < ActiveRecord::Base; end
|
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ConvertReasonToJsonInAnomalyNotifications < ActiveRecord::Migration[7.0]
|
class ConvertReasonToJsonInAnomalyNotifications < ActiveRecord::Migration[7.0]
|
||||||
|
class AnomalyNotification < ApplicationRecord
|
||||||
|
end
|
||||||
|
|
||||||
def up
|
def up
|
||||||
AnomalyNotification.where("reason LIKE '%value:%'").find_each do |anomaly_notification|
|
AnomalyNotification.where("reason LIKE '%value:%'").find_each do |anomaly_notification|
|
||||||
reason = anomaly_notification.reason
|
reason = anomaly_notification.reason
|
||||||
@ -14,6 +17,4 @@ class ConvertReasonToJsonInAnomalyNotifications < ActiveRecord::Migration[7.0]
|
|||||||
def down
|
def down
|
||||||
change_column :anomaly_notifications, :reason, :string
|
change_column :anomaly_notifications, :reason, :string
|
||||||
end
|
end
|
||||||
|
|
||||||
class AnomalyNotification < ActiveRecord::Base; end
|
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user