【问题标题】:On Migration: undefined method `to_sym' for nil:NilClass迁移时:nil:NilClass 的未定义方法“to_sym”
【发布时间】:2011-06-05 19:04:09
【问题描述】:

我正在运行 Rails 3.0.3,但我在迁移时不小心打错了:我创建了一个迁移,它创建了一个类型为 boolen 的新列(应该是 boolean)。我运行了迁移,但 Rails 没有警告我这是无效类型的列,我可以发誓它在以前的版本中这样做了?

现在,每当我尝试在迁移中添加、删除或修改任何内容时,都会收到以下错误:

nil:NilClass 的未定义方法 `to_sym'

我什至无法回滚或丢弃。我保存了早期版本的数据库和文件树,但这个问题让我抓狂,因为这不是我第一次看到这种情况。

如何在不让 Rails 抱怨的情况下有效地删除列(最好不要手动挖掘数据库)?

【问题讨论】:

    标签: ruby-on-rails migration ruby-on-rails-3


    【解决方案1】:

    这是我在使用 rails 迁移时遇到的问题。您拼写错误或错误排列了一个字段的名称。这是你可以做的。

    1. 如果您在出现问题后只进行了一次迁移。
    2. rake db:rollback
    3. 这会让您犯错,您可以更改问题,稍后我将详细介绍。
    4. 如果不是最后一次迁移,请继续使用 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,则进行新的迁移,删除出现问题的表,然后重新生成。我以前不得不这样做。请确保您的订单正确。

    【讨论】:

    • 谢谢山姆。不幸的是,“rake db:rollback”仍然给我 to_sym bs。这严重需要在 Rails 中解决,这是一个公然的问题 -_-
    • 然后删除您的表并再次迁移它。希望你没有很多数据:)
    • 即使是掉落也会导致错误。迁移现在完全没用了。
    • 请完整描述您的环境
    • 谢谢,这是我的应用程序独有的问题。
    【解决方案2】:

    正如您在 cmets 中提到的,一旦记录在您的数据库中,您在尝试删除列时仍然会收到错误消息。

     :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
    

    希望对你有帮助

    【讨论】:

    • 我试过了gist.github.com/spundun/ade33d22ef71bfb61d7d我仍然收到undefined method `to_sym' for nil:NilClass<path to my rvm>/gems/ruby-2.1.1/gems/activerecord-4.1.0.rc1/lib/active_record/connection_adapters/abstract/schema_definitions.rb:216:in `column'
    【解决方案3】:

    您还可以使用数据库工具修复数据库。我遇到了同样的问题,并为 MacOS X 使用了出色的应用程序“Base”。它允许您更改 sqlite 数据库的字段类型。

    在后台,它只是创建一个包含修改后的字段的新表,并从原始表中复制数据。为我工作!

    【讨论】:

    • 您先生今天晚上为我节省了数小时的挫败感。谢谢。
    • 两年后,再次遇到同样的问题,再次回到这个页面,再次保存!谢谢!
    【解决方案4】:

    如果您在回滚时再次遇到同样的问题,请尝试手动删除数据库中的故障列。 (有一个不错的 Firefox 插件,叫做 SQLite Manager。)

    然后运行回滚命令,修复迁移文件中的问题,最后再次迁移。这将帮助您不受 Rails 迁移的限制。

    【讨论】:

      【解决方案5】:

      如果您使用的是 SQLite 数据库,您可能会收到此错误,因为 SQLLite 不提供删除列功能。 http://www.sqlite.org/faq.html#q11

      SQLLite 建议您创建一个临时表,其中仅包含原始表中所需的列,传输数据,然后交换表。

      【讨论】:

      • 哎呀,你不能删除一列吗?什么……说真的?呃。感谢您的提醒。
      • 虽然 SQLite 不允许“ALTER TABLE table_name DROP COLUMN collumn_name”,但这并不意味着你不能使用 remove_column 迁移。 Rails 必须在幕后实现临时表方法。我有大量的迁移,其中我删除了十次列。我来这个问题是因为我在第十次删除时才收到指定的错误消息。
      • 是的,我已经检查了 rails 代码并且 SQLite 适配器确实实现了临时表方法。您会收到此错误,因为 create table 方法正在查找具有 nil 类型的列定义。这可能是一个 Rails 错误。
      • 检查相关表的 schema.rb 文件。我发现:# Could not dump table "simulation_results" because of following StandardError# Unknown type 'real' for column 'elevator_kbtu_site'我在之前的迁移中将real改为float并修复了问题。
      【解决方案6】:

      当我尝试在 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 =&gt; true,它迁移成功。

      我知道这并不完全适用于您的问题。但是如果有人遇到这个问题,很确定他们会找到这个帖子。

      【讨论】:

        【解决方案7】:

        我遇到了几乎完全相同的问题(拼写错误的bolean)并且无法让rake db:rollback 工作,也无法删除列名(因为SQLite3),使用Rails 4.0.2。

        因为我不在乎数据库数据是否被删除,所以我就是这样修复它的:

        1. 删除整个数据库rake db:drop
        2. 编辑[timestamp]_migration_name.rb 文件以正确显示boolean
        3. 再次创建数据库rake db:create
        4. 迁移数据rake db:migrate
        5. (重启网络服务器,等等!)

        【讨论】:

          【解决方案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 而不是 real,当我删除数据库并从头开始重建时问题就消失了。

          在我的例子中,我只将 SQLite 用于测试和开发,其中删除数据库并从头开始重建它是一项常规操作。我们使用不同的数据库,它在生产中没有这个问题,所以更改旧的迁移对我有用。

          【讨论】:

            【解决方案9】:

            我遇到了同样的问题,因为“$rails generate migration add_reset_to_users reset_digest:string \

            reset_sent_at:datetime" 我错过了输入 "$rails generate migration add_reset_to_users reset_digest:string\ reset_sent_at:datetime”。我首先使用 SQLite 的 DB 浏览器删除了“reset”迁移,然后我检查了 schema.rb 文件,因为它不是“t.string”reset_digest“”而是“t. “重置摘要”“。 我将它编辑为“t.string”,然后 rails db:migrate VERSION="previous one" 并且它有效。现在我的最新迁移已关闭。我删除了之前的迁移文件,然后执行“$rails generate migration add_reset_to_users reset_digest:string reset_sent_at:datetime”,我现在得到了我想要的迁移文件。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-01-11
              • 1970-01-01
              • 1970-01-01
              • 2017-04-19
              • 1970-01-01
              • 2011-02-14
              • 2011-01-17
              • 1970-01-01
              相关资源
              最近更新 更多