Allow deletable projects on sandbox and development#4580
Draft
kleintom wants to merge 2 commits into
Draft
Conversation
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
````
Contributor
|
Looking forward -- hoping we can do this @kleintom -- will be very useful (I think?) on DEV when testing various scenarios. |
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This will need specs if we go forward, posting now as it pairs nicely with 'Quick project'.
Potential use cases:
Posting for discussion, open to alternative implementations or deciding this is too dangerous.
Current implementation doesn't allow changing the
is_destroyableflag of a project (through any standard rails mechanism, includingupdate_column- seeimmutable_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.