On Migration: undefined метод `to_sym 'для nil: NilClass

Я запускаю Rails 3.0.3, и я случайно сделал опечатку в моей миграции: я создал миграцию, которая создает новый столбец с типом boolen (он должен был быть boolean). Я выполнил миграцию, и Rails не предупредил меня, что это был недопустимый тип столбца, который я мог бы поклясться в предыдущих версиях?

Теперь, когда я пытаюсь добавить, удалить или изменить что-либо в процессе миграции, я получаю следующую ошибку:

undefined метод `to_sym 'для nil: NilClass

Я не могу даже откат или падение. У меня есть более ранняя версия базы данных и дерева файлов, но эта проблема сводит меня с ума, потому что это не первый раз, когда я это видел.

Как я могу эффективно удалить столбец без запроса Rails (и, желательно, без рубок в базу данных вручную)?

Ответ 1

Это проблема, с которой я столкнулся с миграциями рельсов. Вы ошиблись или неправильно настроили поле с его именем. Вот что вы можете сделать.

  • Если вы сделали только одну миграцию с этой проблемы.
  • rake db:rollback.
  • Это приведет вас к ошибке, и вы можете изменить проблему, о которой я расскажу более подробно.
  • Если это не последняя миграция, продолжайте работу с rake db:rollback, пока вы там не увидите, и проблема исправлена.

Проблема заключается в следующем. Обратите внимание на порядок на первом и написание на втором. Это две проблемы, которые дают мне ту же ситуацию, в которой вы сейчас находитесь, что это to_sym bs.

Например:

 :books, :integer, :name #here I have `integer` before the name
 :books, :name, :integr #here I have the order right but spelling is a problem.

Сообщите мне, есть ли у вас больше вопросов.

Если вы не можете rake db:rollback, то выполните новую миграцию, оставьте таблицу, задающую проблему, и выполните регенерацию. Я должен был это сделать раньше. Просто убедитесь, что вы правильно заказали.

Ответ 2

Если вы используете базу данных SQLite, вы, вероятно, получите эту ошибку, потому что SQLLite не предоставляет функцию столбца drop. http://www.sqlite.org/faq.html#q11

SQLLite предлагает создать временную таблицу с только теми столбцами, которые вам нужны из исходной таблицы, данными передачи и затем заменой таблиц.

Ответ 3

Как вы упомянули в своих комментариях к codeglot, как только запись находится в вашей базе данных, вы все равно получите ошибку при попытке удалить столбец.

 :books, :name, :inntegr #here I have the order right but spelling is a problem.

Чтобы решить эту проблему, вы можете вручную запускать команды sql в своей миграции

  def self.up
    execute "ALTER TABLE books DROP COLUMN name"
  end

надеюсь, что это поможет

Ответ 4

Вы также можете исправить базу данных с помощью инструмента базы данных. У меня была та же проблема и я использовал большое приложение "Base" для MacOS X. Он позволяет вам изменять тип полей баз данных sqlite.

В фоновом режиме он просто создает новую таблицу с измененными полями и копирует данные из оригинала. Работал для меня!

Ответ 5

У меня была почти такая же проблема (с ошибкой bolean) и не удалось получить rake db:rollback для работы, а также не удалить имя столбца (из-за SQLite3), используя Rails 4.0.2.

Как мне было все равно, удалены ли данные БД, вот как я его исправил:

  • Отбросить всю базу данных rake db:drop
  • Отредактируйте файл [timestamp]_migration_name.rb, чтобы правильно сказать boolean
  • Создать базу данных снова rake db:create
  • Перенос данных rake db:migrate
  • (Перезагрузите веб-сервер, et voila!)

Ответ 6

Если вы снова столкнетесь с такой же проблемой при откате, попробуйте вручную удалить неисправный столбец в базе данных. (Есть хороший плагин Firefox, называемый SQLite Manager.)

Затем запустите команду отката, исправьте проблему в файле миграции и, наконец, выполните миграцию снова. Это поможет вам оставаться в ограничениях миграции Rails.

Ответ 7

У меня возникла аналогичная ошибка, когда я пытался создать таблицу соединений в Rails 4 и Ruby 2. Хотя код миграции выглядел хорошо, это вызвало проблему с id => true. Вот как мой код перехода выглядел, когда я получил ошибку.

class CreateJoinTable < ActiveRecord::Migration
  def change
    create_table :table1_table2, :id => true do |t|
        t.references :table1
        t.references :table2
        t.timestamps
    end
  end
end

Это ошибка, которую я получил -

==  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 <top (required)>'
/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 `<main>'

Я удалил :id => true, и он успешно перенесен.

Я знаю, что это точно не относится к вашему вопросу. Но если у кого-то есть эта проблема, достаточно уверен, что они найдут этот поток.

Ответ 8

Ошибка:

undefined method `to_sym' for nil:NilClass

вызвано тем, что Rails не знает тип столбца. Почему он не знает тип? Поскольку тип не находится в файле schema.rb. В моем случае я искал таблицу с проблемой и нашел:

# Could not dump table "simulation_results" because of following StandardError 
# Unknown type 'real' for column 'elevator_kbtu_site'

Я изменил первоначальную миграцию, чтобы использовать float вместо реального, и проблема исчезла, когда я сбросил базу данных и перестроил ее с нуля.

В моем случае я использую только SQLite для тестирования и разработки, где удаление базы данных и ее восстановление с нуля - это обычная операция. Мы используем другую базу данных, которая не имеет этой проблемы в производстве, поэтому изменение старой миграции работает для меня.

Ответ 9

У меня была такая же проблема, потому что вместо этого $rails генерирует миграцию add_reset_to_users reset_digest: string\

reset_sent_at: datetime "I miss typed" $rails генерировать миграцию add_reset_to_users reset_digest: string \ reset_sent_at: datetime ". Сначала я удалил миграцию" reset ", используя браузер БД для SQLite, затем я проверил файл schema.rb, в котором вместо" t.string "reset_digest" "это было" t. "reset_digest" ". Я отредактировал его на" t.string ", затем rails db: migrate VERSION =" предыдущий ", и он сработал. Теперь моя последняя миграция не работает. Я удалил свой предыдущий файл миграции, а затем выполнил" $rails generate migration add_reset_to_users reset_digest: string reset_sent_at: datetime", я получил файл миграции, как я хотел сейчас.