Managing conflict in schema.rb created by Git operation - ruby-on-rails

I created a migration, ran rake db:migrate, which bumped my db/schema.rb version number. Then I did a git fetch origin master and saw that there were changes from my team members. So I did a git stash and a git rebase FETCH_HEAD, followed by a git stash pop. This resulted in a conflict in db/schema.rb over the version number.
Upstream>>>
ActiveRecord::Schema.define(:version => 20110930179257) do
===========
ActiveRecord::Schema.define(:version => 20110930161932) do
<<<Stashed
I think the appropriate fix would be to manually increment the version number to something higher than the upstream.
Is this sensible, or bad news?
Thanks,
Max

If your current database has the correct schema, you should:
Run pending migrations (if any)
rake db:migrate
Overwrite your schema.rb from your current database schema
rake db:schema:dump
And commit

When I find myself with this conflict, I simply migrate the database. Whether there are pending migrations or not, the conflict will be corrected.

tldr
Accept the Upstream version and run rake db:migrate as you'd normally do.
why is that the way to go
Don't worry about the migrations you've created (which are below Upstream version 20110930179257). ActiveRecord uses a table schema_migrations where it puts all of the migrations that have been run. If your migrations aren't on the list but in db/migrate directory, then ActiveRecord will run them.
Here's the table so you can visualise it better:
It's tempting to think that it's actually this line:
ActiveRecord::Schema.define(:version => 20110930179257)
that defines latest migration run, so no migrations with version below it are going to be run. This is fortunately not true. Rails will run any migrations that are in db/migrate folder and not yet in the schema_migrations table.

According to this answer, a conflict is guaranteed. The user has to to manually merge, and set the version as the higher of the two.

Here's what I do when merging master into my feature branch fails over conflicts in db/schema.rb:
$ git merge --abort
$ git checkout master
$ rake db:drop db:create db:migrate
$ git checkout -- db/schema.rb
$ git checkout my_feature_branch
$ rake db:migrate
$ git add db/schema.rb
$ git commit -m 'Updated schema'
$ git merge master

~/bin/update-schema-rb:
#!/usr/bin/env bash
git co master
bin/rake db:reset db:seed
git co -
bin/rake db:migrate

An option is to have a manual version script which is additive only. There you want conflicts. Schema is something that will bite you hard if you don't keep on top of it. So once bitten, twice shy, I don't mind keeping schema and lookup info (list of customer types) with an additive only change management scheme.

I feel the best approach is to do rake db:drop db:create db:migrate to regenerate schema using migrations that exist only on the current branch. That way migrations from other branches won't leak into your schema file and give you headache later - in case if you switch branches a lot.

Related

How to solve Rails merge conflicts with db/structure.sql

I was told that I should follow the below steps if make new migrations in my branch and have merge conflicts with master in the db/structure.sql file.
In the branch, bundle exec rake db:drop
In the branch, bundle exec rake db:create
In master, bundle exec rake db:structure:load
In the branch, git merge master
In the branch, bundle exec rake db:migrate
What are steps 1-3 necessary if all I want to do is align the db/structure.sql file? By merging in master, don't I get the new migrations I haven't ran yet and then by running them, it will update my db/structure.sql?
You're right, dropping and recreating the database to solve a conflict in db/structure.sql (or db/schema.rb for that matter) is a little ridiculous. You should be able to simply run the new migrations and get an updated structure.sql from the db:migrate.
The db/stucture.sql file is simply the database's structure as the database sees it (whereas db/schema.rb is the database's structure in the limited view of it that ActiveRecord has). If there is a conflict in structure.sql, that simply means:
The merge involves new migrations which change the database structure.
The branch you're merging in has run the migrations in a different order so the schema's don't quite match up even though they may be functionally equivalent.
(1) is solved by running the new migrations and possibly fixing any places where the migrations themselves are in conflict. A quick bin/rake db:migrate should fix this and leave you with a new non-conflicted db/structure.sql.
(2) is solved the same way. You could also do a a manual bin/rake db:structure:dump to rebuild db/structure.sql but you'd only do this if you're certain that you really do have this situation; but really, db:migrate will take care of it so there's no reason not to just db:migrate.
Conflicts in db/structure.sql (or db/schema.rb) don't indicate a problem with the db/structure.sql itself, they indicate problems with the database that git can't directly see. The solution to the conflicts is to fix the database.
You can just run bundle exec rake db:structure:dump to re-generate the db/structure.sql file.
For schema.rb I found https://stackoverflow.com/a/3815807/6003161

Rails destroy migration/model on Heroku

Image I created a migration on rails development then I pushed to Heroku;
rails g migration add_smth_to_payments smth:string
rake db:migrate
git add -A
git commit -am "migration smth to payments"
git push heroku master
Then I wanted to destroy this migration again starting from development then push to Heroku;
rake db:rollback
rails d migration add_smth_to_payments
git add -A
git commit -am "destroy migration smth to payments"
git push heroku master
Now, my question is, after destroying the migration (could be model as well), does heroku remove this migration from payments table? I am asking because destroying takes place development
Thank you
Once a migration has been run, the migration file itself is irrelevant. You can delete it, edit it, rename it (as long as the timestamp prefix is left alone) and nothing will happen to the database. In fact, many people periodically delete old migrations to avoid cluttering db/migrate with irrelevant noise.
If you need to undo a migration (i.e. "remove this migration from payments table") then you either write a new migration to undo it or rollback your migrations. Rolling back isn't always an option though: some migrations cannot be reversed and rolling back can reverse migrations you don't want reversed.
All this applies to production/Heroku, development, and anywhere else that you db:migrate.

Heroku: How to update column name in heroku app

Although my app works in my cloud development environment (colud9), We're sorry, but something went wrong. is displayed when I access heroku's url.
I changed column's name in my development environment.
I tried the followings commands;
git commit -a -m "xxx"
git push heroku master
heroku run rake db:migrate
heroku restart
When I check the schema in heroku, column's name haven't been changed.
How can I update column's name in my heroku app?
It could be appreciated if you could give me any suggestion.
I suspect that, you have not added the migration file before creating commit. so you need to add the migration file and then need to create commit. Please follow the following commands.
1) Add Migration files to Git git add .
2) Commit git commit -m "Adding migration file"
3) Push the changes to Heroku git push heroku master - assuming you are using
heroku as your remote name and you are working in the master branch
4)run heroku run rake db:migrate to run the migrations ON HEROKU
5)Following migrations do heroku restar
What you could do is launch a console on heroku:
heroku run console
For e.g you want to update column name for users table
Then do the following:
User.all.each {|user| user.update_attribute :column_name}
In case you want to give some default value to your column, than do the following:
User.all.each {|user| user.update_attribute :column_name, 'value'}
Hope it helps.
run heroku run rake db:version check if the version matches your last migration in your local machine. if not follow #power suggestion.

Rails rake db:rollback on Heroku not working. Now I can't add any new migrations

I have an app that is working fine locally. At one point I tried installed the Act As Taggable gem, which generated a series of migration files. Now I rolled back locally after we voted against using that gem - but after deploying to heroku, it looks like 5 of these migration files did upload to heroku.
I then ran
`heroku run rake db:migrate'
I am now receiving this error
'uninitialized constant AddTaggingsCounterCacheToTags::ActsAsTaggableOn/app/db/migrate/20141107010718_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb:6:in `up'
Now I don't need the "AddTaggingsCounterCacheToTags" but I definitely need a migration that was supposed to run after this.
Any tips on how I can remove this from the production/heroku server? How I can remove only specific migrations and keep the newest migration I made?
Thanks!
Okay folks. I got it.
The problem was that after I removed the files locally, they were still present on git. The process was to remove the migration that was causing the error and then I could have all migrations after come through just fine. Commands are below...
git rm [filename]
git commit -a -m "removed the migrations causing the error from git too"
git push origin master
git push heroku master
heroku run rake db:migrate
There is an issue with having an empty/unnecessary table in the database now, but the important thing is - I can continue to add migrations and my newest features are now working properly on production!
Cheers!

schema.rb not getting updated on rake db:rollback

I have multiple branches each with a migration file. So when I checkout a branch, I do a db:migrate and it would in turn update my schema.rb file.
But, when I checkout another branch and run rake db:migrate, Ideally the changes made my the migration in the previous branch should be removed from schema.rb and the details of the new migration should get into schema.rb
This doesn't happen.
So, I did a rake db:rollback STEP=5, when I checked out a new branch and then did a db:migrate. Even now, I have table details of the migration in previous branch. What I am I doing wrong ? Or is this how Rails behaves?
All performed migrations are saved in table schema_migrations (migration timestamp is saved in DB). When you run rake db:migrate Rails parses directory db/migrate and finds files which are not presented in the table (it compares by timestamp).
Let's you have you have 10 migrations in branch master - schema_migrations has 10 records with timestamps. You create a new branch from master branch_1, create and run there a new migration. Your table schema_migrations has 11 records.
You go back to master and run rake db:migrate - Rails will do NOTHING because no new files are found (in db/migrate). When you run rake db:rollback STEP=5 I suppose (I have never checked it) Rails rollback 5 last migrations from branch MASTER. And it's logical because the last migration (made in branch_1) doesn't exist in branch master (the file with code exists only in branch_1!). So you can't rollback DB changes made in branch_1 from branch master.
What todo?!
I see several strategies:
1) checkout to branch_1 and run rake db:rollback STEP=N (N >= count of new migrations) (You can rollback more migrations then you performed in this branch). Checkout back to master and run rake db:migrate (to perform migrations from master)
2) when you have production dump or good seeds.
Drop current DB, load dump (or seeds), run rake db:migrate
(As for me it is the simplest way when you have production dump!)
PS Maybe smbd else suggest other way to get correct DB in current branch

Resources