2 ideas for (optional?) rules
jjb opened this issue · comments
- do not allow mixing transaction-allowed and transaction-not-allowed changes in one migration
- do not allow more than one transaction-not-allowed change in one migration
This helps keep retries more robust and various problem-solving scenarios easier to deal with.
Hey @jjb, thanks for the suggestion. I don't want to support more checks that don't affect safety right now, so I think these are better as custom checks (maybe someone can create a gist for it).
Gotcha - sounds good - I didn't know about custom checks! Can a check access info about the other invoked methods in a migration? I didn't see anything in checks.rb but maybe I'm missing it. If not possible, will be a fun metaprogramming challenge 😈
You can keep track of previous method calls with:
method_calls = {}
StrongMigrations.add_check do |method, args|
# your check code ...
(method_calls[version] ||= []) << [method, args]
end
Edit: you can use version
to differentiate between migrations
🤯
@ankane can't figure this out: how does one introspect if disable_ddl_transaction!
is present?
add_check
executes inside the migration context, so it'll be the same as inside the migration (self.class.disable_ddl_transaction
).
Edit: That's also how/why version
works, fwiw
came up with this 🎉 which I'll put in an initializer
thanks to having replaced myself with a (very small) script, i no longer have to bug my colleagues about this.
# this scenario can still happen with add_reference, we could inhibit that too
# https://github.com/ankane/strong_migrations/issues/202
strong_migrations_method_calls = {}
StrongMigrations.add_check do |method, args|
next unless 20221104000000 < version
host = connection.raw_connection.host
db = connection.current_database
strong_migrations_method_calls[host] ||= {}
strong_migrations_method_calls[host][db] ||= {}
strong_migrations_method_calls[host][db][version] ||= []
strong_migrations_method_calls[host][db][version] << [method, args]
if strong_migrations_method_calls[host][db][version].size > 1 && disable_ddl_transaction
stop! <<~MESSAGE
If a migration uses disable_ddl_transaction!, it must have only 1 operation.
Put another way: if an operation requires disable_ddl_transaction!, then it must
be in its own migration by itself.
Note: because this is a disable_ddl_transaction! migration, the first operation in
the migration probably succeeded, so if you try to run this again after fixing it you will get a
"something already exists" error. So, you'll need to manually undo the first operation
in this migration to get your dev environment back in good shape.
MESSAGE
end
end
Thanks for sharing