Domanda

Esperienza con Rails / ActiveRecord 2.1.1

  • Crei una prima versione con (ad esempio) ruby ​​script\genera scaffold product title:string description:text image_url:string
  • Questo crea (ad esempio) un file di migrazione chiamato 20080910122415_create_products.rb
  • Applica la migrazione con rake db:migrate
  • Ora aggiungi un campo alla tabella dei prodotti con ruby ​​script\genera migrazione add_price_to_product price:decimal
  • Questo crea un file di migrazione chiamato 20080910125745_add_price_to_product.rb
  • Se provi a eseguire rake db:migrate, in realtà annullerà la prima migrazione, non applicherà quella successiva!Quindi la tua tabella dei prodotti verrà distrutta!
  • Ma se avessi gestito rake da solo, ti avrebbe detto che una migrazione era in sospeso

Tieni presente che l'applicazione del rake db:migrate (una volta che la tabella è stata distrutta) applicherà tutte le migrazioni in ordine.

L'unica soluzione che ho trovato è specificare la versione della nuova migrazione come in:

rake db:migrate version=20080910125745

Quindi mi chiedo:è un nuovo comportamento previsto?

È stato utile?

Soluzione

Dovresti essere in grado di usarlo

rake db:migrate:up 

per forzarlo ad andare avanti, ma rischi di perdere le migrazioni interlacciate di altre persone del tuo team

se corri

rake db:migrate 

due volte, riapplicherà tutte le tue migrazioni.

Riscontro lo stesso comportamento su Windows con SQLite, potrebbe trattarsi di un bug specifico di tale ambiente.

Modificare -- Ho trovato il motivo.Nell'attività railstie database.rake hai il seguente codice:

desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
task :migrate => :environment do
  ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
  ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
  Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end

Quindi nelle mie variabili d'ambiente ho

echo %Version% #=> V3.5.0f

in Rubino

ENV["VERSION"] # => V3.5.0f
ENV["VERSION"].to_i #=>0 not nil !

quindi il compito del rastrello chiama

ActiveRecord::Migrator.migrate("db/migrate/", 0)

e in ActiveRecord::Migrator abbiamo:

class Migrator#:nodoc:
  class << self
    def migrate(migrations_path, target_version = nil)
      case
        when target_version.nil?              then up(migrations_path, target_version)
        when current_version > target_version then down(migrations_path, target_version)
        else                                       up(migrations_path, target_version)
      end
    end

SÌ, rake db:migrate VERSION=0 è la versione lunga di rake db:migrate:down

Modificare - Vorrei andare ad aggiornare il bug del faro ma io il proxy della super compagnia mi proibisce di collegarmi lì

Nel frattempo potresti provare a disimpostare la versione prima di chiamare la migrazione...

Altri suggerimenti

Sono rispettosamente in disaccordo, Tom!Questo È un insetto !!V3.5.0f non è una versione valida per le migrazioni rake.Rake non dovrebbe usarlo per migrare:down solo perché ruby ​​ha scelto di considerare che "V3.5.0f".to_i è 0 ...

Il rastrello dovrebbe lamentarsi ad alta voce che la versione non è valida in modo che gli utenti sappiano cosa succede (tra me e me, controllando che la versione è un timestamp formata aaaa yyyymdd

[Dannazione IE6 che non mi permette di commentare!e no, non posso cambiare browser, grazie aziendale]

Questo non è il comportamento previsto.Stavo per suggerire di segnalare questo come un bug sul faro, ma vedo che l'hai fatto già fatto!Se fornisci ulteriori informazioni (inclusa la versione del sistema operativo/database/Ruby), le darò un'occhiata.

Jean,

Grazie mille per la tua indagine.Hai ragione, e in realtà penso che tu abbia scoperto un bug più grave, il "bug di progettazione" delle specie.

Quello che succede è che rake prenderà qualunque valore passi alla riga di comando e lo memorizzerà come variabili di ambiente.Le attività rake che alla fine verranno chiamate estrarranno semplicemente questi valori dalla variabile di ambiente.Quando db:migrate interroga ENV["VERSION"], in realtà richiede il parametro di versione che hai impostato chiamando rake.Quando chiami rake db:migrate, non passi alcuna versione.

Ma abbiamo una variabile d'ambiente chiamata VERSION che è stata impostata per altri scopi da qualche altro programma (non so ancora quale).E i ragazzi dietro rake (o dietro database.rake) non avevano immaginato che ciò potesse accadere.Questo è un bug di progettazione.Almeno, avrebbero potuto usare nomi di variabili più specifici come "RAKE_VERSION" o "RAKE_PARAM_VERSION" anziché solo "VERSION".

Tom, sicuramente non chiuderò ma modificherò la mia segnalazione di bug su Lighthouse per riflettere queste nuove scoperte.

E grazie ancora Jean per il tuo aiuto.Ho pubblicato questo bug su Lighthouse circa 5 giorni fa e non ho ancora ricevuto risposta!

Rollo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top