* Guard against using VERSION with db:rollback
I recently ran a migration that I needed to rollback, and admittedly, I often forget the proper incantation for this 😅
so the first thing I tried was to run `bin/rake db:rollback VERSION=123454679`. I had hoped that this reverted my
migration back and at first glance I thought it worked. However on closer inspection I realized that it was a different
migration, which initially confused me.
So I looked over the docs and saw that I was using the rake task incorrectly, and promptly corrected my mistake.
Proposal
Looking at the how the `:down` task is defined we see
8dc7439058/activerecord/lib/active_record/railties/databases.rake (L206-L211)
This got me thinking that maybe it would be helpful to have the opposite of this guard defined in `rollback` so that if
`VERSION` is passed it will raise an exception instead of just negecting the extra argument. This could help the user
realize that something went wrong instead of just seeing output and assuming that the rollback happened.
Change
We now raise an execption if `VERSION` is passed when attempting to rollback a migration
* update test name and fix failing test
* remove byebug
[Nick Borromeo + Kate Travers + Rafael Mendonça França]
down is only called with a block from the rake tasks where it passes a
`SCOPE`. Technically this was tested but since we don't run all the
migrations we're not actually testing the down works with a `SCOPE`. To
ensure we're testing both we can run `db:migrate` again to migrate users
and then run `down` with a scope to test that only the bukkits migration
is reverted.
Updates test to prevent having to fix regressions like we did in
4d4db4c.
Rails has some support for multiple databases but it can be hard to
handle migrations with those. The easiest way to implement multiple
databases is to contain migrations into their own folder ("db/migrate"
for the primary db and "db/seconddb_migrate" for the second db). Without
this you would need to write code that allowed you to switch connections
in migrations. I can tell you from experience that is not a fun way to
implement multiple databases.
This refactoring is a pre-requisite for implementing other features
related to parallel testing and improved handling for multiple
databases.
The refactoring here moves the class methods from the `Migrator` class
into it's own new class `MigrationContext`. The goal was to move the
`migrations_paths` method off of the `Migrator` class and onto the
connection. This allows users to do the following in their
`database.yml`:
```
development:
adapter: mysql2
username: root
password:
development_seconddb:
adapter: mysql2
username: root
password:
migrations_paths: "db/second_db_migrate"
```
Migrations for the `seconddb` can now be store in the
`db/second_db_migrate` directory. Migrations for the primary database
are stored in `db/migrate`".
The refactoring here drastically reduces the internal API for migrations
since we don't need to pass `migrations_paths` around to every single
method. Additionally this change does not require any Rails applications
to make changes unless they want to use the new public API. All of the
class methods from the `Migrator` class were `nodoc`'d except for the
`migrations_paths` and `migrations_path` getter/setters respectively.
Ensure that `bin/rails db:migrate` with specified `VERSION` reverts
all migrations only if `VERSION` is `0`.
Raise error if target migration doesn't exist.
Add stronger assertions to rake migration tasks to make sure the user is providing a numeric VERSION
An empty string was getting converted to version = 0. This would in turn pass the presence check.
Address linting warning
Add test for rake task and refactor code to meet expectations
In particular passing VERSION=0 should not raise an error.
Addressed Comments for PR #28485. Trimmed empty lines + change of wording for error message
Adjust test for change of wording in error message
Change condition to follow rails idioms
Apart from specific versioning support, our tests should focus on the
behaviour of whatever version they're accompanying, regardless of when
they were written.
Application code should *not* do this.
`1_valid_people_have_last_names.rb` and
`20150823202140_create_users.rb` are valid migration file name.
But `1_valid_people_have_last_names.rb` is rendered as
`********** NO FILE **********` when `rake db:migrate:status`.
Fix to this bug, this commit includes
* define some API private methdos and a Constant
`match_to_migration_filename?`, `parse_migration_filename`, and
`MigrationFilenameRegexp`
* use these methods in `db:migrate:status` task
Example:
These files are in `db/migrate`
* 1_valid_people_have_last_names.rb
* 20150819202140_irreversible_migration.rb
* 20150823202140_add_admin_flag_to_users.rb
* 20150823202141_migration_tests.rb
* 2_we_need_reminders.rb
* 3_innocent_jointable.rb
we can migrate all of them.
Before
```shell
$ bundle exec rake db:migrate:status
...
Status Migration ID Migration Name
--------------------------------------------------
up 001 ********** NO FILE **********
up 002 ********** NO FILE **********
up 003 ********** NO FILE **********
up 20150819202140 Irreversible migration
up 20150823202140 Add admin flag to users
up 20150823202141 Migration tests
```
After
```shell
$ bundle exec rake db:migrate:status
...
Status Migration ID Migration Name
--------------------------------------------------
up 001 Valid people have last names
up 002 We need reminders
up 003 Innocent jointable
up 20150819202140 Irreversible migration
up 20150823202140 Add admin flag to users
up 20150823202141 Migration tests
```
Closes#20743.
The task `db:_dump` now only dumps the schema if
`ActiveRecord::Base.dump_schema_after_migration` is true. This has
effects:
- `db:migrate:up`
- `db:migrate:down`
- `db:forward`
- `db:rollback`
* Add a config on Active Record named `dump_schema_after_migration`
* Schema dump doesn't happen if the config is set to false
* Set default value of the config to true
* Set config in generated production environment file to false
* Update configuration guide
* Update CHANGELOG
* Fix Migration#reversible by not using `transaction`.
* Adapt mysql adapter to updated api for remove_column
* Update test after aedcd683684d08eaf30623a4b48ce31a31426372
Scope in migrations can be defined by adding suffix in filename,
like: 01_a_migration.blog.rb. Such migration have blog scope.
Scope is automatically added while copying migrations from engine,
so if you want to revert all of the migrations from given engine,
you can just run db:migrate with SCOPE, like:
rake db:migrate SCOPE=blog