Deleted Migration Files and Heroku - ruby-on-rails

I asked about this once already, but I didn't get a working response, and I may have a better way of asking this question.
Long story short, I've deleted some problematic migration files, (the problem is coming from out-of-order migration files; there is an add_column_to_stocks before a create_stocks file), but for whatever reason, heroku continues to want to migrate these old, deleted files. I have no idea where these files are being stored.
If I do a heroku db:migrate:status, this is the response:
Status Migration ID Migration Name
--------------------------------------------------
up 20171231042756 Create articles
up 20171231044214 Add description to articles
up 20180116183526 Create users
up 20180116191414 Add user to articles
up 20180116195212 Add password digest to users
up 20180305082108 Create categories
up 20180305090315 Create article categories
down 20180515064500 Add latest price to stocks
down 20180517202216 Add timetables to stock
down 20180517205823 Add updatedtime to stocks
down 20180521021514 Create user stocks
The problems start at the first down file.
My local migration folder looks more like this:
20171231042756 Create articles
20171231044214 Add description to articles
20180116183526 Create users
20180116191414 Add user to articles
20180116195212 Add password digest to users
20180305082108 Create categories
20180305090315 Create article categories
20180515064499 Create stocks.rb
20180521021514 Create user stocks.rb
No matter what changes I make to my local migration files, it continues to want to migrate these problematic files, so I always get back the response:
PG::UndefinedTable: ERROR: relation "stocks" does not exist
: ALTER TABLE "stocks" ADD "latest_price" decimal
I tried getting into the heroku psql console and deleting them manually, but a delete from schema_migrations where version = 20180515064500 brings back a DELETE 0 response, meaning it hasn't deleted anything.
I'm friggen stumped and I've spent about a week and a half beating my head in over this.
Thank you all in advance!! Any help is appreciated.

File with migration number 20180515064500 should be gone as it is attempting to modify the table which doens't exist.
Remove the files which are breaking the migrations:
git rm db/migrate/20180515064500*.rb
and deploy on heroku.

Look if in your db files, your version of rails is indicated there (5.2 for example):
In your files that are in down mode.
class CurrencyCreateUsers <ActiveRecord :: Migration [5.2]
then rake db: migrate

Related

Fixing rails migration ran on server instead of git repo using Capistrano

I upgraded Spree Commerce from version 3.0 to version 3.1 but forgot to check in the migration files on Git from my local development environment
I instead generated the migration files on the server instead; I ended up committing the migrations from my development environment to git but now I'm having all sorts of problems with deploying because it's trying to run the migration when the tables exists.
I guess I don't really need the migrations to run since it's on the server?
Running rake db:migrate:status on the server shows:
up 20151015124064 Add meta title to page.spree static content
up 20151015124065 Add render as partial for layout for spree pages.spree static content
up 20151015124066 Add pages stores.spree static content
down 20160707102753 Create spree store credits.spree
down 20160707102754 Create spree store credit categories.spree
down 20160707102755 Create spree store credit events.spree
down 20160707102756 Create spree store credit types.spree
down 20160707102757 Add missing indexes.spree
down 20160707102758 Remove duplicated indexes from multi columns.spree
down 20160707102759 Remove user index from spree state changes.spree
down 20160707102760 Add position to spree payment methods.spree
down 20160707102761 Add taxable adjustment total to line item.spree
down 20160707102762 Migrate payment methods display.spree
down 20160707102763 Spree payment method store credits.spree
down 20160707102764 Rename has and belongs to associations to model names.spree
down 20160707102765 Spree store credit types.spree
down 20160707102766 Add discontinued to products and variants.spree
down 20160707102767 Remove shipping method id from spree orders.spree
down 20160707102768 Add id column to earlier habtm tables.spree
down 20160707102769 Add indexes.spree
down 20160707102770 Add missing indices on user.spree auth
down 20160707102771 Remove show in footer from spree pages.spree static content
On my location machine it shows:
up 20151015124064 Add meta title to page.spree static content
up 20151015124065 Add render as partial for layout for spree pages.spree static content
up 20151015124066 Add pages stores.spree static content
up 20160707102753 Create spree store credits.spree
up 20160707102754 Create spree store credit categories.spree
up 20160707102755 Create spree store credit events.spree
up 20160707102756 Create spree store credit types.spree
up 20160707102757 Add missing indexes.spree
up 20160707102758 Remove duplicated indexes from multi columns.spree
up 20160707102759 Remove user index from spree state changes.spree
up 20160707102760 Add position to spree payment methods.spree
up 20160707102761 Add taxable adjustment total to line item.spree
up 20160707102762 Migrate payment methods display.spree
up 20160707102763 Spree payment method store credits.spree
up 20160707102764 Rename has and belongs to associations to model names.spree
up 20160707102765 Spree store credit types.spree
up 20160707102766 Add discontinued to products and variants.spree
up 20160707102767 Remove shipping method id from spree orders.spree
up 20160707102768 Add id column to earlier habtm tables.spree
up 20160707102769 Add indexes.spree
up 20160707102770 Add missing indices on user.spree auth
up 20160707102771 Remove show in footer from spree pages.spree static content
I presume the migration status on the server should be up not down.
Is there any tips how I should approach this?
If you don't have any data to lose you can drop those tables from your sql console and re-run capistrano deployment or you can manually up the migration file from the server by
rake db:migrate:up VERSION=20151015124064
where version is second column of the result of rake db:migrate:status
Note: remember you have to drop those tables on both cases
If you do not want to lose data and do it all over again there is an another approach that you can try.
A migration is marked as up or down based on whether migration version exists as a record within the schema_migrations table.
So, one way you can fix your issue is to add a file app/models/schema_migration.rb containing the following:
class SchemaMigration < ActiveRecord::Base
self.primary_key = :version
attr_accessible :version
# you can call the method below via console or even call
# or execute the commands directly from the rails console
def self.fix_migrations
# basically a list of all migrations that you run on server but are not marked as up
down_migrations = %w(20160707102753 20160707102754 ... 20160707102771)
down_migrations.each do |m|
# this will add an entry in the schema_migrations datatable
# on server so rake db:migrate won't try to run these again
SchemaMigration.create(version: m)
end
end
end
And then via rails console, you execute: SchemaMigration.fix_migrations.
In case you need to run a specific migration again or if you accidentally added a migration version that has never been executed before, you can always remove the entry from schema_migrations using SchemaMigration.find_by_version('xxxx').delete. This will allow rake db:migrate to try to run that migration again.

Remove Model and Table so can start again in Rails

I created a model for comments at the start of a project, but have now come to the realisation I need to create some polymorphic relations so I can use comments with a number of other models as well. Considering the the code I already have etc, I'm thinking it might be easier for me to just start again from scratch so I can build all the views/controllers etc in the correct way for my new polymorphic world.
I see that I can run rails destroy model comments to achieve this but I have two questions on that:
Will this delete the model, migrations AND the actual DB table?
What are the implications when I want to create a new model with the exact same name?
In order to completely remove all columns &
tables that migration has created you need to run:
rails db:migrate:down VERSION=012345678 (where 012345678 should be the version number of your migration)
.............................
rails destroy model Comments
will delete your Model, pending migration, tests and fixtures
So destroy it's the opposite of generate:
$ bin/rails destroy model Oops
invoke active_record
remove db/migrate/20120528062523_create_oops.rb
remove app/models/oops.rb
invoke test_unit
remove test/models/oops_test.rb
remove test/fixtures/oops.yml
And, you can now create a new Model with the same name, as there's no trace of your previous one :)
If you have already migrated the database after creating the model:
First, rollback the changes to the database:
rake db:migrate:down VERSION=20100905201547
where version is the timestamp identifying the migration. For example, if your migration file is called 20170411182948_create_comments.rb then your version parameter should be 20170411182948
Then run
rails destroy model comments
The first command will delete the table from the actual database. The second command will delete the model and the migration file. Make sure you run them in that order as the first command is dependent on the migration file to perform the rollback (which is deleted during the second command).
If you have have not migrated the database:
The table would not have been added to your database. You can go ahead and delete your model and migration files manually or use the destroy command.
You might need to remove the table thoroughly.
Run this :
sqlite3 db/development.sqlite3
Then :
sqlite> drop table table_name;
sqlite> .quit

Reorder/change timestamp on migration files

One of my migration files is referencing another table/model that will will be created further down the migration sequence.
Postgres doesn't like that:
PG::UndefinedTable: ERROR: relation "users" does not exist
So I wonder if there are any potential problems to manually reorder the migration files (by inventing new timestamps/prefixes)?
The affected tables are already down migrated.
When you run rake db:migrate command it compares schema_migrations table and migration files located in db/migrate folder. All the migrations which were not executed receive MigrationClass#up call then.
So starting from the point when your code is already published and/or migrations are run by other users, changing your migrations timestamps/names may lead to unprocessable migration procedure (as schema_migrations will treat a migration with changed timestamp as new, unprocessed one, and try to process it "again"). Possible workaround for this would be to comment the contents of up method for a while and uncomment it back after migrations are done. For fun you can also manipulate schema_migrations table directly from your db console (adding or removing necessary records). Both of these ways smells like a hack though.
Until then... Everything should work flawlessly.
This is what worked for me for this same situation, even though it's a hack.
Rails runs migrations in order of the timestamp, and Rails tracks which migrations have been run by the timestamp part of the migration file name, but not by the rest of the file name. So if you need to change the order of two migrations because the earlier one references the later one you can simply switch the 14 digit timestamp portion of the filenames by renaming both migration files. If the timestamp is off by even one digit Rails will think it's a new migration so write them down before changing them.

Rails migration to clear contents of a database table?

The (occasionally very large) output of some JSON-calls get written into my database to speed things up a little; the app gets the JSON-output pre-rendered from the database.
Every once there's a little change in the content so the output would have been different. I'm looking for a rails migration that I could just include in my deployment for clearing out the specific table storing my JSON code.
You can put that in your migration. Warning, this will delete all data from the table !
Model.connection.execute('DELETE FROM table_name');
Or altenatively you could run some code every day (crontab) to delete everything that is X months old :
def self.delete_old_stuff
month = 3
Model.where("updated_at < ?" , month.months.ago).each{|c| c.destroy}
end
You can call that through the runner command of rails or integrate that a in rake task... I use a similar method to clear old basket in a small ecommerce app.

migrate file timestamp

If I have two migration files:
20110414132423_insert_bulk_data.rb #1st
20111122105951_add_some_columns.rb #2nd
and I run rake db:migrate, is the 1st one run firstly since it has older timestamp??
Since I am in the middle of someone else's code, he made the 20110414132423_insert_bulk_data migration which insert data to table, but this migration file complains an unknown column in the table, then I found the missing column is defined in the 2nd 20111122105951_add_some_columns.rb migration file which has newer timestamp...
How can I get rid of this?
Shortly, yes. The timestamp is used to order migrations and to navigate between them. See more here
delete this migrations
generate two new migrations in the way you need to run

Resources