2011-01-08 18 views
14

Ich verwende Rails 3.0.3 und versehentlich einen Tippfehler in meiner Migration: Ich habe eine Migration erstellt, die eine neue Spalte mit einem Typ boolen (es sollte gewesen sein boolean). Ich habe die Migration durchgeführt, und Rails hat mich nicht gewarnt, dass dies ein ungültiger Spaltentyp ist, den ich in früheren Versionen hätte schwören können.Bei der Migration: undefinierte Methode `to_sym 'für nil: NilClass

Nun, wenn ich versuche, hinzuzufügen, zu entfernen oder ändern etwas in einer Migration ich die folgende Fehlermeldung erhalten:

undefined method `to_sym' for nil:NilClass

ich nicht einmal oder fallen Rollback kann. Ich habe eine frühere Version der Datenbank und des Dateibaums gespeichert, aber dieses Problem macht mich verrückt, weil es nicht das erste Mal ist, dass ich das gesehen habe.

Wie kann ich die Spalte effektiv entfernen, ohne dass Rails sich beschweren muss (und vorzugsweise ohne von Hand in die Datenbank zu graben)?

Antwort

6

Dies ist ein Problem, das ich mit Schienen Migrationen hatte. Sie haben ein Feld mit seinem Namen falsch geschrieben oder falsch sortiert. Hier ist, was Sie tun können.

  1. Wenn Sie nur eine Migration seit dem Problem durchgeführt haben.
  2. rake db:rollback.
  3. Das wird Sie zu dem Fehler bringen und Sie können das Problem ändern, über das ich später sprechen werde.
  4. Wenn es nicht die letzte Migration ist weiter mit rake db:rollback bis Sie dort sind und das Problem behoben ist.

Das Problem ist in etwa so. Beachten Sie die Reihenfolge auf der ersten und die Schreibweise auf der zweiten. Dies sind zwei Probleme, die mir die gleiche Situation haben, in der Sie gerade sind, das ist das to_sym bs.

Zum Beispiel;

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

Lassen Sie mich wissen, wenn Sie weitere Fragen haben.

Wenn Sie nicht rake db:rollback können dann machen Sie eine neue Migration, lassen Sie die Tabelle mit dem Problem, und regenerieren. Ich musste das schon mal machen. Stellen Sie nur sicher, dass Sie Ihre Bestellung richtig erhalten.

+3

Dank Sam Leider. "Rake db:. Rollback" noch mir die to_sym bs geben Dies muss ernst in Rails behoben werden, ist es ein eklatantes Problem- –

+0

yeah, es ist wirklich lahm – s84

+2

Dann lassen Sie Ihre Tabelle und migrieren Sie es wieder.Hoffee Sie haben nicht viele Daten :) – s84

9

Wie Sie in Ihren Kommentaren zu Codeglot erwähnt haben, sobald der Datensatz in Ihrer Datenbank ist, erhalten Sie immer noch den Fehler, wenn Sie versuchen, die Spalte zu entfernen.

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

Um dieses Problem zu überwinden Sie manuell SQL-Befehle in Ihrer Migration

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

Hoffnung dieses

+0

Ich habe es versucht https://gist.github.com/spundun/ade33d22ef71bfb61d7d Ich bekomme immer noch undefined method \ 'to_sym 'für nil: NilClass /gems/ruby-2.1.1/gems/ activerecord-4.1.0.rc1/lib/active_record/connection_adapters/abstract/schema_definitionen.rb: 216: in \ 'spalte' ' – Spundun

4

Sie auch die Datenbank beheben, ein Datenbank-Tool können hilft ausführen können. Ich hatte das gleiche Problem und benutzte die großartige Anwendung "Base" für MacOS X. Sie können den Feldtyp der SQLite-Datenbanken ändern.

Im Hintergrund erstellt es nur eine neue Tabelle mit den geänderten Feldern und kopiert die Daten aus dem Original. Arbeitete für mich!

+0

Sie haben mir heute Abend Stunden der Frustration erspart. Vielen Dank. –

+0

Zwei Jahre später hatte das selbe Problem wieder auf dieser Seite wieder, wieder gespart! Vielen Dank! –

1

Wenn Sie beim Rollback erneut auf dasselbe Problem stoßen, versuchen Sie, die fehlerhafte Spalte in der Datenbank manuell zu entfernen. (Es gibt ein nettes Firefox-Plugin namens SQLite Manager.)

Dann führen Sie den Rollback-Befehl, beheben Sie das Problem in der Migrationsdatei und schließlich wieder migrieren. Dies hilft Ihnen dabei, die Einschränkungen der Rails-Migration einzuhalten.

15

Wenn Sie die SQLite-Datenbank verwenden, erhalten Sie wahrscheinlich diesen Fehler, weil SQLLite die Funktion zum Löschen von Spalten nicht bereitstellt.

SQLLite schlägt vor, dass Sie eine temporäre Tabelle mit nur den Spalten erstellen, die Sie aus Ihrer ursprünglichen Tabelle benötigen, Daten übertragen und dann die Tabellen austauschen.

+2

Augh, du kannst keine Spalte fallen lassen? Was zum ... Ernst? Erg. Danke für die Köpfe hoch. –

+0

Obwohl SQLite "ALTER TABLE Tabellenname DROP COLUMN spaltenname" nicht zulässt, heißt das nicht, dass Sie eine remove_column-Migration nicht verwenden können. Rails muss die temporäre Tabellenmethode unter den Abdeckungen implementieren. Ich habe eine große Reihe von Migrationen, in denen ich die Spalten zehnmal entferne. Ich bin auf diese Frage gekommen, weil ich die angegebene Fehlermeldung erst beim zehnten Entfernen bekommen habe. –

+0

Ja, ich habe den Rails-Code untersucht und der SQLite-Adapter implementiert die temporäre Tabellenmethode. Sie erhalten diesen Fehler, weil die create table-Methode eine Spaltendefinition mit dem Typ nil findet. Dies kann ein Schienenfehler sein. –

1

Ich habe einen ähnlichen Fehler, als ich versuchte, eine Join-Tabelle in Rails 4 und Ruby 2 zu erstellen. Obwohl der Migrationscode für mich gut aussah, war es id => true Zeile, die das Problem verursacht. So sah mein Migrationscode aus, als ich den Fehler bekam.

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 

Dies ist der Fehler, den ich bekam -

== 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>' 

I :id => true und die es migriert erfolgreich entfernt.

Ich weiß, dass dies nicht für Ihre Frage genau gilt. Aber wenn jemand dieses Problem hat, ist es ziemlich sicher, dass er diesen Thread findet.

3

Ich hatte fast genau das gleiche Problem (hatte bolean falsch geschrieben) und konnte nicht rake db:rollback zu arbeiten, noch den Spaltennamen (wegen SQLite3), mit Rails 4.0.2.

Da ich nicht egal, wenn die DB-Daten gelöscht wurde, das ist, wie ich es fest:

  1. Tropfen die gesamte Datenbank rake db:drop
  2. Bearbeiten Sie die Datei korrekt [timestamp]_migration_name.rbboolean
  3. sagen erstellen die Datenbank erneut rake db:create
  4. Migrieren Sie die Daten rake db:migrate
  5. (Starten Sie den Webserver, et voila!)
0

Der Fehler:

undefined method `to_sym' for nil:NilClass 

verursacht, weil Rails nicht den Typ der Spalte nicht kennt. Warum kennt es den Typ nicht? Weil der Typ nicht in der Datei schema.rb enthalten ist. In meinem Fall habe ich nach der Tabelle mit dem Problem und fand:

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

änderte ich die ursprüngliche Migration Schwimmer verwenden anstelle von realen und das Problem ging weg, wenn ich die Datenbank gelöscht und es von Grund auf neu aufgebaut.

In meinem Fall verwende ich nur SQLite für Test und Entwicklung, wo das Löschen der Datenbank und das Neuaufbau von Grund auf eine normale Operation ist. Wir verwenden eine andere Datenbank, die dieses Problem nicht in der Produktion hat, also funktioniert die Änderung der älteren Migration für mich.

0

hatte ich das gleiche Problem, denn statt „$ Schienen Migration add_reset_to_users reset_digest erzeugen: 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.

Verwandte Themen