Skip to content

Allow deletable projects on sandbox and development#4580

Draft
kleintom wants to merge 2 commits into
SpeciesFileGroup:developmentfrom
kleintom:4400_deletable_project
Draft

Allow deletable projects on sandbox and development#4580
kleintom wants to merge 2 commits into
SpeciesFileGroup:developmentfrom
kleintom:4400_deletable_project

Conversation

@kleintom

Copy link
Copy Markdown
Contributor

This will need specs if we go forward, posting now as it pairs nicely with 'Quick project'.

Potential use cases:

  • mainly cases where you want a clean slate to repeatedly test some kind of import without fowling your main project or stumbling over leftovers of previous attempts.
    • dwc imports
    • super autocomplete
    • batch loads (maybe combined with super autocomplete)
    • gaz imports

Posting for discussion, open to alternative implementations or deciding this is too dangerous.

Current implementation doesn't allow changing the is_destroyable flag of a project (through any standard rails mechanism, including update_column - see immutable_boolean.rb), but this is not yet enforced at the db level - see the first commit's message for (not-db-agnostic) code to do that.

Code mainly from chatgpt.

Environment constraints to come.

DB-level constraint to make sure is_destroyable never changes (multiple dbs just to show it's doable in other dbs):

```ruby
class ForbidDestroyableFlipTrigger < ActiveRecord::Migration[7.2]
  def up
    case ActiveRecord::Base.connection.adapter_name
    when 'PostgreSQL'
      execute <<~SQL
        CREATE OR REPLACE FUNCTION forbid_destroyable_flip() RETURNS trigger AS $$
        BEGIN
          IF NEW.is_destroyable IS DISTINCT FROM OLD.is_destroyable THEN
            RAISE EXCEPTION 'Changing projects.is_destroyable is not allowed';
          END IF;
          RETURN NEW;
        END;
        $$ LANGUAGE plpgsql;
        DROP TRIGGER IF EXISTS trg_forbid_destroyable_flip ON projects;
        CREATE TRIGGER trg_forbid_destroyable_flip
        BEFORE UPDATE OF is_destroyable ON projects
        FOR EACH ROW EXECUTE FUNCTION forbid_destroyable_flip();
      SQL
    when 'Mysql2'
      execute <<~SQL
        DROP TRIGGER IF EXISTS trg_forbid_destroyable_flip;
        CREATE TRIGGER trg_forbid_destroyable_flip
        BEFORE UPDATE ON projects
        FOR EACH ROW
        BEGIN
          IF NEW.is_destroyable <> OLD.is_destroyable THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Changing projects.is_destroyable is not allowed';
          END IF;
        END;
      SQL
    when 'SQLite', 'SQLite3'
      execute <<~SQL
        DROP TRIGGER IF EXISTS trg_forbid_destroyable_flip;
        CREATE TRIGGER trg_forbid_destroyable_flip
        BEFORE UPDATE OF is_destroyable ON projects
        FOR EACH ROW
        WHEN NEW.is_destroyable <> OLD.is_destroyable
        BEGIN
          SELECT RAISE(ABORT, 'Changing projects.is_destroyable is not allowed');
        END;
      SQL
    else
      say "Adapter #{ActiveRecord::Base.connection.adapter_name} not recognized; skipping trigger."
    end
  end

  def down
    case ActiveRecord::Base.connection.adapter_name
    when 'PostgreSQL'
      execute "DROP TRIGGER IF EXISTS trg_forbid_destroyable_flip ON projects;"
      execute "DROP FUNCTION IF EXISTS forbid_destroyable_flip();"
    when 'Mysql2', 'SQLite', 'SQLite3'
      execute "DROP TRIGGER IF EXISTS trg_forbid_destroyable_flip;"
    end
  end
end
````
@kleintom kleintom marked this pull request as draft October 13, 2025 14:40
@debpaul

debpaul commented Oct 13, 2025

Copy link
Copy Markdown
Contributor

Looking forward -- hoping we can do this @kleintom -- will be very useful (I think?) on DEV when testing various scenarios.

@kleintom

Copy link
Copy Markdown
Contributor Author

Consider the use of rails engines so that the delete code is never even present on production: https://guides.rubyonrails.org/engines.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants