From 517b3b9e8a8929878ed521cc4439e25a8226ccd5 Mon Sep 17 00:00:00 2001 From: SOO Date: Wed, 30 Sep 2026 00:58:45 +0800 Subject: [PATCH 1/2] allow deletion of project template fields only when cascaded through project template --- app/models/project_template_field.rb | 20 ++++++++++++-------- db/schema.rb | 3 +++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/models/project_template_field.rb b/app/models/project_template_field.rb index 3a81fa4e..4092ba90 100644 --- a/app/models/project_template_field.rb +++ b/app/models/project_template_field.rb @@ -35,17 +35,21 @@ def option_list private def cannot_delete_title_field - return unless is_project_title? - - errors.add(:base, 'Cannot delete the Project Title field') - throw :abort + if destroyed_by_association and destroyed_by_association.active_record.name == "ProjectTemplate" + return + elsif !is_project_title? + errors.add(:base, 'Cannot delete the Project Title field') + throw :abort + end end def cannot_delete_if_in_use - return unless project_instance_fields.exists? - - errors.add(:base, "Field “#{label}” is in use and can’t be removed") - throw :abort + if destroyed_by_association and destroyed_by_association.active_record.name == "ProjectTemplate" + return + elsif !project_instance_fields.exists? + errors.add(:base, "Field “#{label}” is in use and can’t be removed") + throw :abort + end end def force_title_required diff --git a/db/schema.rb b/db/schema.rb index 7afe4305..45c5a861 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,6 +11,9 @@ # It's strongly recommended that you check this file into your version control system. ActiveRecord::Schema[8.0].define(version: 2026_08_29_082339) do + # These are extensions that must be enabled in order to support this database + enable_extension "pg_catalog.plpgsql" + create_table "comments", force: :cascade do |t| t.integer "user_id", null: false t.string "text", null: false From 2dbfd5d05c765cae8e09f56529869ec39cc6b735 Mon Sep 17 00:00:00 2001 From: SOO Date: Wed, 30 Sep 2026 01:29:07 +0800 Subject: [PATCH 2/2] changed evaluation order inside model --- app/models/project_template_field.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/models/project_template_field.rb b/app/models/project_template_field.rb index 4092ba90..e1cb2c13 100644 --- a/app/models/project_template_field.rb +++ b/app/models/project_template_field.rb @@ -1,5 +1,10 @@ class ProjectTemplateField < ApplicationRecord belongs_to :project_template + + # has to be before the lines below or else the cascade delete would've happened before the check + before_destroy :cannot_delete_if_in_use + before_destroy :cannot_delete_title_field + has_many :project_instance_fields, dependent: :destroy acts_as_list scope: :project_template, add_new_at: :bottom @@ -14,8 +19,6 @@ class ProjectTemplateField < ApplicationRecord validates :position, numericality: { only_integer: true }, allow_nil: true before_validation :force_title_required - before_destroy :cannot_delete_if_in_use - before_destroy :cannot_delete_title_field FIELD_TYPE_LABELS = { 'shorttext' => 'Short Text', @@ -37,7 +40,7 @@ def option_list def cannot_delete_title_field if destroyed_by_association and destroyed_by_association.active_record.name == "ProjectTemplate" return - elsif !is_project_title? + elsif is_project_title? errors.add(:base, 'Cannot delete the Project Title field') throw :abort end @@ -46,7 +49,7 @@ def cannot_delete_title_field def cannot_delete_if_in_use if destroyed_by_association and destroyed_by_association.active_record.name == "ProjectTemplate" return - elsif !project_instance_fields.exists? + elsif project_instance_fields.exists? errors.add(:base, "Field “#{label}” is in use and can’t be removed") throw :abort end