I started out using Rolify in a Rails app and created a migration to set up its tables about 15 migrations ago. I've now decided to replace it with my own code and want to revert that one migration without touching all of the later migrations. The database is in use now, so reverting 15, removing the one I don't want to add and then applying the subsequent 14 would destroy data.
Section 3.11 of the Rails Guide on migrations suggests that this can be done by creating a new migration which reverts the specific old migration by name:
class FixupExampleMigration < ActiveRecord::Migration
def change
revert ExampleMigration
create_table(:apples) do |t|
t.string :variety
end
end
end
I tried to customise this to my context, which would look like this:
class RolifyDestroyRoles < ActiveRecord::Migration
def change
revert RolifyCreateRoles
end
end
(The first line of my original Rolify migration was class RolifyCreateRoles < ActiveRecord::Migration). However, I get a namespace error:
StandardError: An error has occurred, this and all later migrations canceled:
uninitialized constant RolifyDestroyRoles::RolifyCreateRoles/home/slack/rails/tracker/db/migrate/20150127093921_rolify_destroy_roles.rb:3:in `change'
Maybe something has changed in Rails 4. Does anyone know how I should refer to RolifyCreateRoles so that Rails can find it?
Reverting a specific migration in rails :
Let's say we have a migration :
db/migrate/20150127071749_create_users.rb
revert:
rake db:migrate:down VERSION=20150127071749
setup again:
rake db:migrate:up VERSION=20150127071749
Hope that helps :)
Related
I tried to create a migration to add roles to my user tables but i accidentally typed AddRolesToUsers instead of AddRoleToUser. So i tried creating a new migration with the correct AddRoleToUsers but when i tried to run rake db:migrate i got an error :
SQLite3::SQLException: duplicate column name: role: ALTER TABLE "users" ADD "role" integer/Users/miguel/.rvm/gems/ruby-2.2.1/gems/sqlite3-1.3.11/lib/sqlite3/database.rb:91:in `initialize'
I tried rake db:migrate:down VERSION= do delete the one I had to type on but i keep getting the same error . PS: i deleted the migration file manually after running rake db:migrate:down VERSION=
rails g migration AddRoleToUsers role:integer
migration file :
class AddRoleToUsers < ActiveRecord::Migration
def change
add_column :users, :role, :integer
end
end
When you ran the first migration, the role column was added to the Users table. The error on the second migration tells you that much.
To clear the migration pending error, you need to comment out the add_column statement in the new migration.
i.e,
class AddRoleToUsers < ActiveRecord::Migration
def change
# add_column :users, :role, :integer
end
end
Then run the migration. This way, the new migration should run successfully.
You can now uncomment it and delete the previous migration, so that when you deploy, only the newer migration is run and the role column is added successfully.
In that case right click and delete both migration files and start again. The error exists because it thinks you want to add two columns both named role to your users table
UPDATE
In that case, if role already exists in your users table, a migration must've been successfully run and there is no need to run another. As long as the role column is there, trying to add another column called role will always give you an error. If you wanted to test that you are still able to add new columns you can always check by creating a test migration AddSomethingToUsers something:string and rake db:migrate to test, then rake db:rollback to undo..but it all seems like it's worked so I probably my wouldn't mess with it too much.
I have the following migrations
Problem is that rake db:migrate is not executing the first migration and no users table is created.
What could be the reason for this?
What could be the reason for this?
Main reason is probably that you've already ran the migration - or perhaps later migrations - and Rails therefore does not think it needs to run it.
A good way to see if this is the case is to open your db/schema.rb file:
You'll see the latest migration your schema is running. If this supersedes the one you're trying to invoke, it will not run.
--
Fixes
You could generate a new migration, and copy the code over:
$ rails g migration AddUsers2
You'd then add the following:
#db/migrate/_____.rb
class AddUsers2 < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.timestamps
end
end
end
Alternatively, you could wipe your DB and start again. This can be achieved using rake schema:load. THIS WILL WIPE ALL DATA AND START AGAIN
Running through Michael Hartl's well known Rails tutorial, hit this snag.
I have this in a migration file, created by rails generate model etc:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
Later, I added this second migration file:
class AddIndexToUsersEmail < ActiveRecord::Migration
def change
add_index :users, :email, unique: true
end
end
To try and update the database to include the new one, I followed the instructions and ran rake db:migrate, but this gives me an error telling me I'm trying to create a table that already exists, which is to say I'm clearly missing something.
Am I...supposed to delete the first migration? That wouldn't make any sense. What to do?
(These are the only files under db/migrate)
if you realy want to see what migrations have been ran into the database, you can inspect your app database, there is a table called schema_migrations, in there you can see the unique id of each migration as a row for example is your migration is called: 20130402190449_add_flagand_table.rb, you should see the number 20130402190449 as a row of that table, hope i gave you some guidance
What you can do is rollback couple of migration and re-run.
You can rollback migration like this
#rake db:rollback STEP=2
and then run
#rake db:migrate
Hope it should work
My issues was my 2nd to last migration ran and it was trying to rerun that migration again after i added a new migration.
I ended up just commenting out the code inside the one it was trying to rerun, and then ran rake db:migrate then uncommented the migration code.
This way the schema does not break and it fixes whatever bug occurred.
I need to add some columns to a table in my schema. Can someone tell me the best way to do this?
The following seems incomplete or wrong since the schema.rb file did not update to include the new column and all of the corresponding view files (edit,index,new,show) did not update to include the new column. Not to mention the bloat of all of those migration classes that get generated. Thanks
ruby script/generate migration RecordLabelToAlbums record_label:string
exists db/migrate
create db/migrate/20121130125859_record_label_to_albums.rb
Creates this:
class RecordLabelToAlbums < ActiveRecord::Migration
def self.up
end
def self.down
end
end
I then added this:
class RecordLabelToAlbums < ActiveRecord::Migration
def self.up
add_column :albums, :record_label, :text
end
def self.down
remove_column :albums, :record_label
end
end
The I ran:
rake db:migrate
Got This:
Mysql::Error: Table 'albums' already exists: CREATE TABLE albums (id int(11) DEFAULT NULL auto_increment PRIMARY KEY, created_at datetime, updated_at datetime)
The code you added is correct.
The error suggests that for some reason your system appears to think it has not yet run the original migration that created the albums table. The state of migrations (in Rails 2) is specified in a table in the database called schema_migrations -- if this gets confused then it will try to re-run migrations. I am not sure what might cause it to get confused, but I do recall this happened a couple times back in 2008 when I was using Rails 2.x.
The table is simple -- you can see what's in it from a SQL prompt -- just the names of migrations it thinks it has run, I think.
If you don't mind losing some data, you can try rake db:rollback or even rake db:reset to get back to the beginning. rake db:rollback STEP=2 will rollback the last 2 migrations.
If you need the data, correct the contents of the table by adding one or more new records referencing the migrations in app/db/migrations that may have been missed. The order is important, I think (the format changed a little in Rails 3, I don't recall how).
Any time you want to add or change the database schema, use rails to generate a migration, and then run rake db:migrate once it's ready to go.
And just asking: is there any way you can move to Rails 3. It's been out for years now, and Rails 4 is coming soon. You'll find yourself in a backwater of incompatibilities, deprecations, security and performance issues and so on if you don't take the hit and upgrade.
An old one of my ruby on rails migrations contains both the actual migration but also an action to modify data:
class AddTypeFlagToGroup < ActiveRecord::Migration
def self.up
add_column :groups, :selection_type, :string
Group.reset_column_information
Group.transaction do
Group.all.each do |group|
group.selection_type = group.calculate_selection_type
group.save
end
end
end
def self.down
remove_column :groups, :selection_type
end
end
In this migration there are the usual add_column and remove_column migration statements. But there are also some model specific method calls.
I wrote this a couple of weeks ago. Since then, I have removed my Group model, which gives an error when I do a full migration with :reset.
rake db:migrate:reset
(in /Users/jesper/src/pet_project)
[...]
== AddTypeFlagToGroup: migrating =============================================
-- add_column(:groups, :selection_type, :string)
-> 0.0012s
rake aborted!
An error has occurred, this and all later migrations canceled:
uninitialized constant AddTypeFlagToGroup::Group
The thing is that in the current revision of my code, Group does not exist. How should I handle this "the rails way"??
I am thinking I could modify the migration by commenting out the Group.xxx stuff, but is this a wise way to go?
There is no value in leaving the group stuff in your migration now that it is gone from your project. I'd just edit the migration, drop everything from the db and migrate from scratch. There isn't even a reason to comment it out (you are using version control right?)
Also, I believe the "rails way" with migrations is spelled "Arrrrgh!"