可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm running Rails 3.0.3 and I accidentally made a typo in my migration: I created a migration that creates a new column with a type of boolen
(it should have been boolean
). I ran the migration and Rails didn't warn me that this was an invalid type of column, which I could have sworn it did in previous versions?
Now whenever I try to add, remove, or modify anything in a migration I get the following error:
undefined method `to_sym' for nil:NilClass
I can't even rollback or drop. I have an earlier version of the database and file tree saved, but this problem is driving me crazy because it isn't the first time I've seen this happen.
How can I effectively remove the column without having Rails complain (and preferably without digging into the database by hand)?
回答1:
This is a problem that I have had with rails migrations. You misspelled or misordered a field with its name. Here is what you can do.
- If you have only done one migration since the problem.
rake db:rollback
. - That will get you to the mistake and you can change the problem which I will talk about more later.
- If it is not the last migration keep going with
rake db:rollback
until you are there and the problem is fixed.
The problem is something like this. Notice the order on the first one and the spelling on the second one. These are two problems that have giving me the same situation you are in right now which is that to_sym
bs.
For example;
:books, :integer, :name #here I have `integer` before the name :books, :name, :integr #here I have the order right but spelling is a problem.
Let me know if you have more questions.
If you cannot rake db:rollback
then make a new migration, drop the table giving the problem, and regenerate. I've had to do that before. Just make sure you get your order right.
回答2:
If you are using the SQLite database, you probably getting this error because SQLLite doesn't provide the drop column feature. http://www.sqlite.org/faq.html#q11
SQLLite suggests that you create a temporary table with only the columns that you need from your original table, transfer data, and then swap the tables.
回答3:
As you mentioned in your comments to codeglot once the record is in your database you still get the error when trying to remove the column.
:books, :name, :inntegr #here I have the order right but spelling is a problem.
To overcome this problem you can manually run sql commands in your migration
def self.up execute "ALTER TABLE books DROP COLUMN name" end
hope this helps
回答4:
You can also fix the database using a database tool. I had the same problem and used the great application "Base" for MacOS X. It allows you to change the field type of sqlite databases.
In the background it just creates a new table with the modified fields and copies the data from the original one. Worked for me!
回答5:
I had almost exactly the same issue (had misspelled bolean
) and couldn't get rake db:rollback
to work, nor dropping the column name (because of SQLite3), using Rails 4.0.2.
As I didn't care if the DB data was deleted, this is how I fixed it:
- Drop the entire database
rake db:drop
- Edit the
[timestamp]_migration_name.rb
file to correctly say boolean
- Create the database again
rake db:create
- Migrate the data
rake db:migrate
- (Restart the web server, et voila!)
回答6:
If you face the same issue on rollback again, try to remove the faulty column in the database manually. (There is a nice Firefox plugin called SQLite Manager.)
Then run the rollback command, fix the issue in the migration file, and finally migrate again. This will help you stay in the constraints of Rails migration.
回答7:
I got a similar error when I was trying to create a join table in Rails 4 and Ruby 2. Although the migration code looked good to me, it was id => true
line that caused the issue. Here is how my migration code looked like when I got the error.
class CreateJoinTable true do |t| t.references :table1 t.references :table2 t.timestamps end end end
This is the error I got -
== CreateJoinTable: migrating ======================================= -- create_table(:table1_table2, {:id=>true}) rake aborted! An error has occurred, this and all later migrations canceled: undefined method `to_sym' for true:TrueClass/Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/schema_definitions.rb:215:in `column' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:370:in `column' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/schema_definitions.rb:68:in `primary_key' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:363:in `primary_key' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/schema_statements.rb:181:in `create_table' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:625:in `block in method_missing' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:597:in `block in say_with_time' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:597:in `say_with_time' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:617:in `method_missing' /Users/aswin/Code/webbloks/db/migrate/20131101044153_create_property_join_tables.rb:3:in `change' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:571:in `exec_migration' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:555:in `block (2 levels) in migrate' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:554:in `block in migrate' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:294:in `with_connection' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:553:in `migrate' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:709:in `migrate' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:959:in `block in execute_migration_in_transaction' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:1005:in `block in ddl_transaction' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `block in transaction' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:210:in `within_new_transaction' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `transaction' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/transactions.rb:209:in `transaction' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:1005:in `ddl_transaction' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:958:in `execute_migration_in_transaction' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:920:in `block in migrate' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:916:in `each' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:916:in `migrate' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:764:in `up' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/migration.rb:742:in `migrate' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/railties/databases.rake:42:in `block (2 levels) in ' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval' /Users/aswin/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `'
I removed :id => true
and the it migrated successfully.
I know this doesn't apply to your question exactly. But if someone is having this issue, pretty sure they'll find this thread.
回答8:
The error:
undefined method `to_sym' for nil:NilClass
is caused because Rails doesn't know the type of the column. Why doesn't it know the type? Because the type isn't in the schema.rb file. In my case I looked for the table with the problem and found:
# Could not dump table "simulation_results" because of following StandardError # Unknown type 'real' for column 'elevator_kbtu_site'
I changed the original migration to use float instead of real and the problem went away when I dropped the database and rebuilt it from scratch.
In my case I only use SQLite for test and development where dropping the database and rebuilding it from scratch is a regular operation. We use a different database which doesn't have this issue in production, so changing the older migration works for me.
回答9:
I had the same issue, because instead "$rails generate migration add_reset_to_users reset_digest:string \
reset_sent_at:datetime" I miss typed "$rails generate migration add_reset_to_users reset_digest:string\ reset_sent_at:datetime". I first removed the "reset" migration using DB browser for SQLite, then I checked schema.rb file, in that instead of " t.string "reset_digest" " it was " t. "reset_digest" ". I edited it to "t.string" then rails db:migrate VERSION="previous one" and it worked. Now my latest migration is down. I deleted my previous migration file and then executed "$rails generate migration add_reset_to_users reset_digest:string reset_sent_at:datetime", I got the migration file as I wanted now.