Use calling migration version for safe_version?
when calling revert
#244
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.
The Problem
Let's suppose you initialize your StrongMigrations like so
But, let's say you have a pair of migrations that StrongMigrations would consider "dangerous" from a long time ago that look like this
Under these circumstances, StrongMigrations will fail on the RevertDangerousMigration, even though I would expect it to pass without error since both of these migrations occur before the configured start_after.
My debugging leads me to believe that this is because, when we call revert DangerousMigration, the underlying dangerous operation call on the migration being reverted triggers the method_missing logic that ultimately checks the safety of the migration being reverted, but StrongMigration has no context of this migration's version since the migration is called as a class with no context for the original filename. In other words, StrongMigrations doesn't have knowledge of the version of the migration being reverted, only that of the migration doing the revert. When StrongMigrations doesn't see a version, it assumes the migration is unsafe, causing it to fail.
The Solution
I had the thought to override the revert method and check the migration's version there before moving onto the child migration. I'm open to other ideas about how best to solve this.
Ultimately, these changes make it so that, in a migration where you call the
revert
method, StrongMigrations compares the calling migration's version againstStrongMigration.start_after
to decide whether or not to run checks on the reverted migration.Because of the details of the way the tests are set up, the reason why these tests would fail before the changes aren't obvious at first, so let me explain.
In the failing test, the first migration
AddTableDangerously
is given the default migration version123
that is defined here.When we call
assert_safe RevertAddTableDangerously
in the test, we only end up calling the helpermigrate
function on theRevertAddTableDangerously
migration. When this migration then calls thechange
method on the migration it is reverting,AddTableDangerously
, we don't give it the default123
version, leaving it asnil
, which then fails theversion_safe?
method here.This is not identical to my tests with the gem in a dummy live app, but it's identical in that the child migration that is being reverted also has a
nil
version when running with the dummy app, causing it to fail before the changes are implemented.Now, with the changes, we implement a
def revert
method that checks the version, then passes everything on tosuper
with asafety_assured
block if the calling migration's version is safe.I looked to
active_record/migration.rb#revert
for the method signature that I needed to override and then pass ontosuper
.