Migration issue in Ruby-on-rails
Hey guys, when I first begin a rails project, the model user was designed and created. After all the migration part, it successful created the table "users" at postgres. Well, then after doing some changes during the project, I realized that was missing an attribute/new column at the table.
So what I did was delete the table users from postgres and add a new column at my first migration ruby class:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.string :password
t.string :email
t.string :authorization_token //this is the 开发者_Python百科new attribute that I insert
t.datetime :created_at
t.datetime :updated_at
t.timestamps
end
end
def self.down
drop_table :users
end
end
So, when I run again the db:migrate hopping that a new user table will be created with the new attribute :authorization_token, it doesn't work, but with no errors.
(I know that I should not remove the table, there is another smart way to do it)
A tip for working with Rails -- do not hand modify your tables using SQL. When you saw the problem you should have written a new migration like @nruth showed. Running the rake:migrate command would have worked fine for you.
In this case since you've already deleted your 'users' table you now have the problem that your database schema is out of sync with what Rails thinks it is. To fix this problem you can either get the database schema to roughly match what Rails thinks it is by hand creating the 'users' table, running the down migration and then then the up migration. Or you can get Rails up to speed with the fact that the 'users' table no longer exists. Rails stores migration info in either a schema_info table (Rails < 2.1) or schema_migrations table (Rails >= 2.1). If you remove that table then Rails will think the schema does not exist and try to run all the up migrations and recreate the 'users' table for you again.
Lastly, over time you may accumulate a number of migrations that individually add a column or two that you forgot to include. If you haven't yet shipped or aren't in production yet, then you can write a migration that sort of baselines your table. It would look something like this:
class CreateBaselineUsers < ActiveRecord::Migration
def self.up
create_table :users, :force => true do |t|
t.string :name
...
This will forcibly drop the table and recreate it with all the attributes that you want.
Migrations are run once & stored in the database as having been used (take a look in the schema_migrations table). You could try using rake db:migrate:reset to re-run your initial migration, but it's better to just add new migrations (you won't want to blow away your database when it has data in it) as follows:
script/generate migration add_authorization_token_to_users authorization_token:string
which will generate something similar to the following:
class AddAuthorizationTokenToUsers < ActiveRecord::Migration
def self.up
change_table :users do |t|
t.string :authorization_token //this is the new attribute that I insert
end
end
def self.down
remove_column :users, :authorization_token
end
end
To see how add/remove column, change_table, etc work, take a look at ActiveRecord::ConnectionAdapters::SchemaStatements at http://api.rubyonrails.org or http://guides.rubyonrails.org/migrations.html
精彩评论