diff --git a/app/controllers/admin/experiment_projects_controller.rb b/app/controllers/admin/experiment_projects_controller.rb index f72afffac551b9cfe5d7e49280e1b56413e0b871..53d51ff2f275246a0d6471e4f7c2ec6881aa0df3 100644 --- a/app/controllers/admin/experiment_projects_controller.rb +++ b/app/controllers/admin/experiment_projects_controller.rb @@ -27,43 +27,43 @@ module Admin end def create - @experiment_project = ExperimentProject.create experiment_project_params - - failed = update_roles(experiment_project_params_with_teachers['teachers'], - :teacher, @experiment_project) - - if @experiment_project.persisted? - if failed.empty? - flash[:success] = "Successfully created experiment #{@experiment_project.name}" - else - flash[:danger] = 'Experiment was created, but teachers could not be set' - end - redirect_to admin_experiment_project_url(@experiment_project) - else - flash[:danger] = 'Failed to create experiment' - render 'new' - end + @experiment_project = ExperimentProject.create(merge(experiment_project_params)) + helpers.flash_crud_msg(@experiment_project, + extra_checks: { + 'Equality Group' => lambda do + @experiment_project.equality_group_id ||= @experiment_project.id + @experiment_project.save + @experiment_project.persisted? + end, + Role.model_name.human => lambda do + update_roles( + experiment_project_params_with_teachers['teachers'], :teacher, @experiment_project + ).none? + end + }, + on_success: proc { redirect_to admin_experiment_project_url(@experiment_project) }, + on_part_failure: proc { redirect_to admin_experiment_project_url(@experiment_project) }, + on_failure: proc { render 'new' }) end def update - failed = update_roles(experiment_project_params_with_teachers['teachers'], - :teacher, @experiment_project) - - if @experiment_project.update(experiment_project_params) && failed.empty? - flash[:success] = 'Successfully updated the experiment' - redirect_to admin_experiment_project_url(@experiment_project) - else - flash[:danger] = 'Failed to update the experiment' - render 'edit' - end + @experiment_project.update(experiment_project_params) + helpers.flash_crud_msg(@experiment_project, html: false, + extra_checks: { + Role.model_name.human => lambda do + update_roles( + experiment_project_params_with_teachers['teachers'], :teacher, @experiment_project + ).none? + end + }, + on_success: proc { redirect_to admin_experiment_project_url(@experiment_project) }, + on_part_failure: proc { redirect_to admin_experiment_project_url(@experiment_project) }, + on_failure: proc { render 'edit' }) end def destroy - if @experiment_project.destroy - flash[:success] = 'Successfully destroyed the experiment' - else - flash[:danger] = 'Failed to destroy the experiment' - end + @experiment_project.destroy + helpers.flash_crud_msg(@experiment_project) redirect_to admin_experiment_projects_url end diff --git a/app/models/experiment_project.rb b/app/models/experiment_project.rb index 015a5c0fec49ca4ca43f51e692922c8d5f4c67df..b4d063cd39ce7ffde63371f07194add7290c58a9 100644 --- a/app/models/experiment_project.rb +++ b/app/models/experiment_project.rb @@ -25,27 +25,41 @@ class ExperimentProject < ApplicationRecord "Round #{round}: #{name}" end - def advance - ExperimentProject.create(attributes.except('id').merge(round: round + 1)) - end - + # Creates a copy of this project but with the given round set. + # @param round_number [Integer] the round number + # @return [ExperimentProject] def copy_with_round(round_number) - ExperimentProject.create(attributes.except('id').merge(round: round_number, original_experiment_project_id: id)) + ExperimentProject.create( + attributes.except('id') + .merge(round: round_number, + original_experiment_project_id: id, + equality_group_id: equality_group_id) + ) end - # Fix me: other projects based on original_id + # Gets the projects which are equivalent to this one, which are not in the same round. + # This method returns both projects with equal names as well as the projects which were copied from this one. def other_same_projects ExperimentProject.where(name: name).where.not(round: round) + .or(ExperimentProject.where(equality_group_id: equality_group_id).where.not(round: round).where.not(id: id)) end + # + # @return [ExperimentProject, Nil] the original project from which this project was copied (if any) def original - ExperimentProject.where(id: original_experiment_project_id).where.not(id: id) + ExperimentProject.where(id: original_experiment_project_id) + .where.not(id: id) + .take end + # Whether this project was copied from another project. + # NOTE: If the original was deleted, this method will report false. + # @return [Boolean] def original? - original.empty? + original.blank? end + # @return [ActiveRecord::Relation] the users that belong to this project def users users1.or(users2) end diff --git a/db/migrate/20220621225654_add_equality_group_id_to_experiment_project.rb b/db/migrate/20220621225654_add_equality_group_id_to_experiment_project.rb new file mode 100644 index 0000000000000000000000000000000000000000..c5f8c03cb6af90a1970d0213d98fa2d735d7a252 --- /dev/null +++ b/db/migrate/20220621225654_add_equality_group_id_to_experiment_project.rb @@ -0,0 +1,22 @@ +class AddEqualityGroupIdToExperimentProject < ActiveRecord::Migration[6.1] + def change + add_column :experiment_projects, :equality_group_id, :int, index: true + + ExperimentProject.where.find_each do |exp| + base = exp + until base.original_experiment_project_id.nil? + nbase = ExperimentProject.find_by(id: base.original_experiment_project_id) + + # Safeguard for copy of no longer existing original + break if nbase.nil? + + # Safeguard for cyclic base + break if nbase.id == base.id + + base = nbase + end + # Set equality group id to the id of the base project + exp.equality_group_id = base.id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index fb8d6fa6fe33f2cb52dbbb9c1531ac06f0b31bda..c024fe44e94c99a0c909cc4b5b04fa53f902df47 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_06_11_101357) do +ActiveRecord::Schema.define(version: 2022_06_21_225654) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false @@ -298,9 +298,11 @@ ActiveRecord::Schema.define(version: 2022_06_11_101357) do t.integer "min_couples", default: 0 t.boolean "theoretical", default: false t.bigint "original_experiment_project_id" + t.integer "equality_group_id" t.index ["course_edition_id"], name: "index_experiment_projects_on_course_edition_id" t.index ["department_id"], name: "index_experiment_projects_on_department_id" t.index ["original_experiment_project_id"], name: "index_experiment_projects_on_original_experiment_project_id" + t.index ["equality_group_id"], name: "index_experiment_projects_on_equality_group_id" end create_table "faculties", force: :cascade do |t|