How to use simple-numbered migrations versions in Rails? - ruby-on-rails

I'm using NetBeans + Rails 2.3.8.
I notice that whenever I generate a model, the migration filename for it includes the date and time:
Model Name: User
Migration File Name : 20100916172053_create_users.rb
But when I see books (like Agile Web Development with Rails), the (rake-generated examples int it) all show simple numbers like 001_create_users, 002_create_sessions etc.
How do I get that simple numbering scheme (it looks neater, easier on the eyes when searching for a model)?
Or is it better to just go with the flow and not bother about what kind of versioning number is used?

You can add this to config/environment.rb
config.active_record.timestamped_migrations = false
Note that the default was changed to timestamps because it (the numbering version) causes problems in multi-developer environments. When two developers both create a migration between source control updates, the migrations will have the same numbers. If you are working alone that would not be a problem.
Also, I'm not sure how it will work if you already have existing migrations, so be careful if that is the case.

The migrations wth the timestamp are the newer form as that allows more than one person at a time to add a migration to the project. This is particularily useful in projects with more than one developer as with the old numbered approach you would need to add the migrations in lock step or renumber them.
So I would recommend that you stick with the timestamp form.
However if you still want to use the older numbered forms you can do as #ngoozeff suggested and add:
config.active_record.timestamped_migrations = false
to either your environment.rb or an initializer.

Related

Ruby on Rails Database Deployment with Gerrit

I'm considering using Ruby on Rails for my next project. Understanding the deployment of a rails website is easy enough to understand (sounds like I'll be using Phusion Passenger)
But now I'm trying to figure out the database. I see a lot about "database migrations", which allow me to update the database using ruby code. I also see that I'm allowed to create both an up and down variant of these migrations.
However, I can only fathom how this works cleanly in a single direction. Imagine if I suddenly say "The color column cannot be null". So, the up will make it required and give all NULL entries a default value. But what will the down do? If you care about it being identical to how it started, you can't just set the default values back to NULL.
This doesn't really matter much for releases to production. That will likely just be done in a single direction (in the up direction). However, I want to use Gerrit for code reviews as well as setting up a bot to run a build before allowing check-ins...
So how could that work? From one code review to the next, the build server will check out the new set of code, and run the migrations? But when this happens, it won't even retain the migration code from before, so how could it run the down steps? As an simpler example, I do not see how I could check out an old version of the code and "db migrate" backwards.
Yes, you can't check out an old version of the code and then run a down migration from a newer version of the code. You would need to run the down migration before rolling back to the older code.
There are many, many cases where a down migration is just not practical or possible. That's not necessarily a bad thing. It just means that you have defined a 'point of no return', where you won't be able to restore your database to an earlier state.
Migrations like creating a table or adding a column are easily reversed by simply destroying that table or removing that column. However, if you are doing something more complex, such as adding default values or moving data around, then you can tell Rails that it's not possible to reverse this migration:
def down
raise ActiveRecord::IrreversibleMigration
end
I would recommend that Gerrit should never assume anything about the database. It should start with a fresh database each time a new version is deployed, and run db:migrate to run all your migrations. You can use gems like factory_girl to populate your app with demo data for testing purposes.

conflict model names in surveyor gem

I'm about installing surveyor gem, i followed the instructions there but when i executed
this line to install the gem components:
script/rails generate surveyor:install
I got these conflicts
conflict db/migrate/20120716110951_create_questions.rb
Overwrite /home/saka/modares/db/migrate/20120716110951_create_questions.rb? (enter "h" for help) [Ynaqdh] h
I know that the problem is these conflict model names in the gem and in the existing application as i already have a model named Question.
How to resolve this conflict?
This behavior is a result of an design decision in surveyor. We would like to allow people to run rails generate surveyor:install every time they upgrade surveyor, and get new migrations and changed files. The generator finds migrations with the same class name, preserves the timestamp, and presents the conflict to the user if it is different. One thing that may affect your decision moving forward is that if you do maintain your existing create_questions migration, you'll have to contend with this conflict every time you upgrade surveyor. There are a few solutions:
Surveyor could be changed to support name-spaced, configurable, or otherwise modifiable model names. This will most certainly take time, and there are currently no issues for this feature (but feel free to add one).
You could rename your migration and the generator will run. Remove the create_questions and add_correct_answer_id_to_questions migrations, and remove questions from the add_api_ids migration. Make sure your question model matches the surveyor question model as documented in the wiki (there's no guarantee we'll keep the diagram in sync). More definitively, you may create a blank rails project, add surveyor, run the generator and migrations, and then look at db/schema.rb. You'll have to keep your question model in sync with surveyor's manually.
You could rename your model. If it has existing functionality besides surveyor's, you'll probably want to go this route anyway.
How about renaming your Question Model? You Basically have to create a migration for renaming (or change the initial migration if you don't need the migration if you don't have production data yet) and find all occurrences of Question/question in your app and rename them accordingly. It's a bit of work but not a real problem.

Undoing a Migration Error

How do you go about changing column names and types in your rails app? Do you create a new migration to make the changes, or do you rollback, edit your migration file, and then migrate again?
What's the "proper" way to do this in Rails?
It sort of depends on when this happened in your development cycle, If you recently made the change and haven't pushed it out into a public repo, then you indeed might want to do the rollback thing and then edit the migration files and migrate again, just to keep things clean. But if it's a change to a migration that's a few migrations back then you should create a new migration that changes the rows and columns to the "new" old values.
Well, to undo a migration you typically want to roll it back:
bundle exec rake db:rollback
Where VERSION= can also be specified. If you wanted to change it to something entirely new, you would make a new migration. Typically you shouldn't be touching old migrations at all.
Rails gives you the choice of creating a migration and changing it a various of ways. So there is no "ruby developers" technique of choice.
However, every time you create a migration, a file is created, and it represents the history of your development. There are a lot of cases that a simpler file should be uselfull, like a code that other ruby beginners would have to look at and modify. On other cases may be necessary to an advanced developer understand changes and improvements made on the code, specially if it is a code running for a long time (some years maybe).

Can i stop Rails from using a timestamp prefix for migrations after some migrations have been generated using timestamps?

There are about a hundred or so migrations in my migrate folder with numeric prefixes, then about a hundred or so with timestamp prefixes, so i guess at some point Rails version was updated. Now I want to go stop Rails from using timestamp prefixes as i prefer numeric prefixes. What is the best way to accomplish this, or is this even possible? One approach may be to manually rename the prefixes in their sort order, and then go to dev, staging and production databases and change the timestamps by the new numbers, but this approach looks messy. is there some other way to accomplish this?
Timestamped migrations are awesome if you have a team, or if you want to branch and work on something else. However you can change how migrations are named with a config setting.
#environment.rb
config.active_record.timestamped_migrations = false
Also.... the lazy_developer plugin I maintain has a task to transform all of your migration files into a brand-new migration. I make no warranties that it will work for you, but I've used it on a few projects to get things where i want them to be.
http://github.com/napcs/lazy_developer
It basically takes schema.rb and makes a new migration from it. It tries to handle your indexes too, but it does use a timestamp for the migration number, setting the new migration it creates to the same name as the last migration so that your database's versioning is correctly maintained.
Again, no guarantee this will work, so backup or branch your project first!
If I were you, I'd leave this alone. It's convention to have the migration names, and really, you only have to use them at most once. If you're deploying to a new server or checking the project out to a new machine, you should really use rake db:schema:load instead as it's much faster. Migrations are meant for development and incremental db changes. And like I said, timestamped migrations rock for multiple users.

Why does new Rails db migration file start with datestamp instead of sequence number?

Whenever I use script/generate to generate a new scaffold for a change to my Rails database, the new migration file is prepended by a datestamp (e.g. 200903140912_create_users.rb) instead of a sequence number (e.g. 004_create_users.rb).
I then have to manually change the file name to fit in with the rest of the migration files.
Does anyone know how to fix this?
System: Mac OS X Leopard 10.5.6
Rails: v2.2.2
Ruby: v1.8.6
This was introduced in Rails 2.1. According to the migrations docs, you can revert it by setting config.active_record.timestamped_migrations to false in config/environment.rb.
I'm not sure why they made the decision, but I can tell you how it's made my life easier. On a team it was common for two people to create migrations at roughly the same time. If the last production migration was 007 then both of the new ones would be 008. The second person to commit would have a headache on their hands trying to sort it out, and the timestamps make that conflict a lot less likely.
The decision was made because when people worked together on the same project they would often try to create a migration with their new changes. This would lead to the issue where two people were working on the same project making separate changes but both generating a migration with the same number. The Rails core team decided to change it to a UTC timestamp since it's way less likely (but still possible!) that two (or more) developers would be creating a migration in the same second, rather than the same sequence.
It is also worth mentioning that using the UTC timestamp helps with sequence that migrations are run when the developers might be in separate time zones.

Resources