Extract Contributor concern as abstract class
During documentation of the pair programming feature, we noticed that the Contributor should be an abstract class, which is parent for the User and the ProgrammingGroup. With this commit, we perform these changes.
This commit is contained in:

committed by
Sebastian Serth

parent
37e5dfaba1
commit
dab8f777b3
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Contributor
|
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
included do
|
|
||||||
has_many :submissions, as: :contributor
|
|
||||||
end
|
|
||||||
end
|
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
module ContributorCreation
|
module ContributorCreation
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
include Contributor
|
|
||||||
|
|
||||||
ALLOWED_CONTRIBUTOR_TYPES = [InternalUser, ExternalUser, ProgrammingGroup].map(&:to_s).freeze
|
ALLOWED_CONTRIBUTOR_TYPES = [InternalUser, ExternalUser, ProgrammingGroup].map(&:to_s).freeze
|
||||||
|
|
||||||
|
48
app/models/contributor.rb
Normal file
48
app/models/contributor.rb
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Contributor < ApplicationRecord
|
||||||
|
self.abstract_class = true
|
||||||
|
|
||||||
|
has_many :anomaly_notifications, as: :contributor, dependent: :destroy
|
||||||
|
has_many :user_exercise_interventions, as: :contributor
|
||||||
|
has_many :runners, as: :contributor, dependent: :destroy
|
||||||
|
|
||||||
|
has_many :submissions, as: :contributor
|
||||||
|
|
||||||
|
def learner?
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def teacher?
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def admin?
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def internal_user?
|
||||||
|
is_a?(InternalUser)
|
||||||
|
end
|
||||||
|
|
||||||
|
def external_user?
|
||||||
|
is_a?(ExternalUser)
|
||||||
|
end
|
||||||
|
|
||||||
|
def programming_group?
|
||||||
|
is_a?(ProgrammingGroup)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
displayname
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_page_context
|
||||||
|
{
|
||||||
|
id:,
|
||||||
|
type: self.class.name,
|
||||||
|
consumer: try(:consumer)&.name, # Only a user is associated with a consumer.
|
||||||
|
displayname:,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
@ -1,19 +1,14 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ProgrammingGroup < ApplicationRecord
|
class ProgrammingGroup < Contributor
|
||||||
include Contributor
|
|
||||||
|
|
||||||
has_many :anomaly_notifications, as: :contributor, dependent: :destroy
|
|
||||||
has_many :programming_group_memberships, dependent: :destroy
|
has_many :programming_group_memberships, dependent: :destroy
|
||||||
has_many :external_users, through: :programming_group_memberships, source_type: 'ExternalUser', source: :user
|
has_many :external_users, through: :programming_group_memberships, source_type: 'ExternalUser', source: :user
|
||||||
has_many :internal_users, through: :programming_group_memberships, source_type: 'InternalUser', source: :user
|
has_many :internal_users, through: :programming_group_memberships, source_type: 'InternalUser', source: :user
|
||||||
has_many :testruns, through: :submissions
|
has_many :testruns, through: :submissions # Only a single user starts testruns, but the group has access to them through their submissions.
|
||||||
has_many :runners, as: :contributor, dependent: :destroy
|
has_many :events, dependent: :destroy # Only a single user creates events, but the group might be attributed to them optionally.
|
||||||
has_many :events, dependent: :destroy
|
|
||||||
has_many :events_synchronized_editor, class_name: 'Event::SynchronizedEditor', dependent: :destroy
|
has_many :events_synchronized_editor, class_name: 'Event::SynchronizedEditor', dependent: :destroy
|
||||||
has_many :pair_programming_exercise_feedbacks, dependent: :destroy
|
has_many :pair_programming_exercise_feedbacks, dependent: :destroy
|
||||||
has_many :pair_programming_waiting_users, dependent: :destroy
|
has_many :pair_programming_waiting_users, dependent: :destroy
|
||||||
has_many :user_exercise_interventions, as: :contributor
|
|
||||||
belongs_to :exercise
|
belongs_to :exercise
|
||||||
|
|
||||||
validate :min_group_size
|
validate :min_group_size
|
||||||
@ -21,14 +16,6 @@ class ProgrammingGroup < ApplicationRecord
|
|||||||
validate :no_erroneous_users
|
validate :no_erroneous_users
|
||||||
accepts_nested_attributes_for :programming_group_memberships
|
accepts_nested_attributes_for :programming_group_memberships
|
||||||
|
|
||||||
def external_user?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def internal_user?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def learner?
|
def learner?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
@ -45,10 +32,6 @@ class ProgrammingGroup < ApplicationRecord
|
|||||||
Exercise
|
Exercise
|
||||||
end
|
end
|
||||||
|
|
||||||
def programming_group?
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def add(user)
|
def add(user)
|
||||||
# Accessing the `users` method here will preload all users, which is otherwise done during validation.
|
# Accessing the `users` method here will preload all users, which is otherwise done during validation.
|
||||||
internal_users << user if user.internal_user? && users.exclude?(user)
|
internal_users << user if user.internal_user? && users.exclude?(user)
|
||||||
@ -56,23 +39,10 @@ class ProgrammingGroup < ApplicationRecord
|
|||||||
user
|
user
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
|
||||||
displayname
|
|
||||||
end
|
|
||||||
|
|
||||||
def displayname
|
def displayname
|
||||||
"Programming Group #{id}"
|
"Programming Group #{id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_page_context
|
|
||||||
{
|
|
||||||
id:,
|
|
||||||
type: self.class.name,
|
|
||||||
consumer: nil, # A programming group is not associated with a consumer.
|
|
||||||
displayname:,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def programming_partner_ids
|
def programming_partner_ids
|
||||||
users.map(&:id_with_type)
|
users.map(&:id_with_type)
|
||||||
end
|
end
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class User < ApplicationRecord
|
class User < Contributor
|
||||||
self.abstract_class = true
|
self.abstract_class = true
|
||||||
|
|
||||||
attr_reader :current_study_group_id
|
attr_reader :current_study_group_id
|
||||||
|
|
||||||
belongs_to :consumer
|
belongs_to :consumer
|
||||||
has_many :anomaly_notifications, as: :contributor, dependent: :destroy
|
|
||||||
has_many :authentication_token, dependent: :destroy
|
has_many :authentication_token, dependent: :destroy
|
||||||
has_many :comments, as: :user
|
has_many :comments, as: :user
|
||||||
has_many :study_group_memberships, as: :user
|
has_many :study_group_memberships, as: :user
|
||||||
@ -15,15 +14,12 @@ class User < ApplicationRecord
|
|||||||
has_many :programming_groups, through: :programming_group_memberships, as: :user
|
has_many :programming_groups, through: :programming_group_memberships, as: :user
|
||||||
has_many :exercises, as: :user
|
has_many :exercises, as: :user
|
||||||
has_many :file_types, as: :user
|
has_many :file_types, as: :user
|
||||||
has_many :submissions, as: :contributor
|
|
||||||
has_many :participations, through: :submissions, source: :exercise, as: :user
|
has_many :participations, through: :submissions, source: :exercise, as: :user
|
||||||
has_many :user_proxy_exercise_exercises, as: :user
|
has_many :user_proxy_exercise_exercises, as: :user
|
||||||
has_many :user_exercise_interventions, as: :contributor
|
|
||||||
has_many :testruns, as: :user
|
has_many :testruns, as: :user
|
||||||
has_many :interventions, through: :user_exercise_interventions
|
has_many :interventions, through: :user_exercise_interventions
|
||||||
has_many :remote_evaluation_mappings, as: :user
|
has_many :remote_evaluation_mappings, as: :user
|
||||||
has_many :request_for_comments, as: :user
|
has_many :request_for_comments, as: :user
|
||||||
has_many :runners, as: :contributor
|
|
||||||
has_many :events
|
has_many :events
|
||||||
has_many :events_synchronized_editor, class_name: 'Event::SynchronizedEditor'
|
has_many :events_synchronized_editor, class_name: 'Event::SynchronizedEditor'
|
||||||
has_many :pair_programming_exercise_feedbacks
|
has_many :pair_programming_exercise_feedbacks
|
||||||
@ -31,8 +27,6 @@ class User < ApplicationRecord
|
|||||||
has_one :codeharbor_link, dependent: :destroy
|
has_one :codeharbor_link, dependent: :destroy
|
||||||
accepts_nested_attributes_for :user_proxy_exercise_exercises
|
accepts_nested_attributes_for :user_proxy_exercise_exercises
|
||||||
|
|
||||||
scope :with_submissions, -> { where('id IN (SELECT user_id FROM submissions)') }
|
|
||||||
|
|
||||||
scope :in_study_group_of, lambda {|user|
|
scope :in_study_group_of, lambda {|user|
|
||||||
unless user.admin?
|
unless user.admin?
|
||||||
joins(:study_group_memberships)
|
joins(:study_group_memberships)
|
||||||
@ -46,18 +40,6 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
validates :platform_admin, inclusion: [true, false]
|
validates :platform_admin, inclusion: [true, false]
|
||||||
|
|
||||||
def internal_user?
|
|
||||||
is_a?(InternalUser)
|
|
||||||
end
|
|
||||||
|
|
||||||
def external_user?
|
|
||||||
is_a?(ExternalUser)
|
|
||||||
end
|
|
||||||
|
|
||||||
def programming_group?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def learner?
|
def learner?
|
||||||
return true if current_study_group_id.nil?
|
return true if current_study_group_id.nil?
|
||||||
|
|
||||||
@ -86,19 +68,6 @@ class User < ApplicationRecord
|
|||||||
study_group_memberships.where(study_group: current_study_group_id).limit(1)
|
study_group_memberships.where(study_group: current_study_group_id).limit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
|
||||||
displayname
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_page_context
|
|
||||||
{
|
|
||||||
id:,
|
|
||||||
type: self.class.name,
|
|
||||||
consumer: consumer.name,
|
|
||||||
displayname:,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.find_by_id_with_type(id_with_type)
|
def self.find_by_id_with_type(id_with_type)
|
||||||
if id_with_type[0].casecmp('e').zero?
|
if id_with_type[0].casecmp('e').zero?
|
||||||
ExternalUser.find(id_with_type[1..])
|
ExternalUser.find(id_with_type[1..])
|
||||||
|
@ -28,7 +28,7 @@ end
|
|||||||
|
|
||||||
# delete all present records
|
# delete all present records
|
||||||
Rails.application.eager_load!
|
Rails.application.eager_load!
|
||||||
(ApplicationRecord.descendants - [ActiveRecord::SchemaMigration, User]).each(&:delete_all)
|
(ApplicationRecord.descendants - [ActiveRecord::SchemaMigration, Contributor, User]).each(&:delete_all)
|
||||||
|
|
||||||
# delete file uploads
|
# delete file uploads
|
||||||
FileUtils.rm_rf(Rails.public_path.join('uploads'))
|
FileUtils.rm_rf(Rails.public_path.join('uploads'))
|
||||||
|
Reference in New Issue
Block a user