6

Rails / ActiveRecord 2.1.1 の経験者

  • (たとえば) ruby​​ script\generate scaffold product title:string description:text image_url:string で最初のバージョンを作成します
  • これにより、(たとえば) 20080910122415_create_products.rb という移行ファイルが作成されます。
  • rake db:migrate で移行を適用します
  • ここで、ruby script\generate migration add_price_to_product price:decimal を使用して商品テーブルにフィールドを追加します。
  • これにより、20080910125745_add_price_to_product.rb という移行ファイルが作成されます。
  • rake db:migrate を実行しようとすると、実際には最初の移行が元に戻され、次の移行は適用されません! したがって、製品テーブルは破棄されます!
  • しかし、rake を単独で実行すると、1 つの移行が保留中であることが通知されます。

rake db:migrate を適用すると (テーブルが破棄されたら)、すべての移行が順番に適用されることに注意してください。

私が見つけた唯一の回避策は、新しい移行のバージョンを次のように指定することです。

rake db:migrate version=20080910125745

だから私は疑問に思っています:これは予想される新しい動作ですか?

4

4 に答える 4

1

あなたは使用できるはずです

rake db:migrate:up 

強制的に進めますが、チームの他の人からのインターリーブされた移行を見逃すリスクがあります

あなたが実行する場合

rake db:migrate 

2 回、すべての移行が再適用されます。

SQLite を使用する Windows でも同じ動作が発生します。そのような環境に固有のバグである可能性があります。

編集- 理由がわかりました。railstie database.rake タスクには、次のコードがあります。

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

次に、環境変数に

echo %Version% #=> V3.5.0f

ルビーで

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

したがって、 rake タスクが呼び出されます

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

ActiveRecord::Migrator には次のものがあります。

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

はい、rake db:migrate VERSION=0のロングバージョンですrake db:migrate:down

編集- 灯台のバグを更新しますが、スーパーカンパニーのプロキシがそこに接続することを禁止しています

それまでの間、migrate を呼び出す前に Version の設定を解除してみてください ...

于 2008-09-16T09:39:54.230 に答える
0

ジャン、

調査ありがとうございます。あなたは正しいです、そして実際にあなたは種の「デザインバグ」のより深刻なバグを発見したと思います。

何が起こっているのかというと、rakeはコマンドラインに渡した値を取得し、それらを環境変数として保存します。最終的に呼び出されるrakeタスクは、環境変数からこの値を取得するだけです。db:migrateがENV ["VERSION"]を照会すると、実際には、rakeを呼び出して設定したバージョンパラメーターを要求します。rake db:migrateを呼び出すとき、どのバージョンも渡しません。

しかし、他のプログラムによって他の目的のために設定されたVERSIONと呼ばれる環境変数があります(私はまだどれもしていません)。そして、rakeの背後にいる(またはdatabase.rakeの背後にいる)人々は、これが起こるとは考えていませんでした。これは設計上のバグです。少なくとも、「VERSION」だけでなく、「RAKE_VERSION」や「RAKE_PARAM_VERSION」などのより具体的な変数名を使用することもできます。

トム、私は絶対に閉じませんが、これらの新しい発見を反映するために灯台に関する私のバグレポートを編集します。

そして、もう一度ジャンにあなたの助けに感謝します。このバグを5日間のアガオのように灯台に投稿しましたが、まだ答えがありません!

ロロ

于 2008-09-16T10:41:03.473 に答える
0

私は丁重にトムに同意しません!これバグです!! V3.5.0f は、rake の移行に有効なバージョンではありません。Ruby が "V3.5.0f".to_i が 0 であると見なすことを選択したという理由だけで、Rake は migrate:down にそれを使用すべきではありません ...

Rake は VERSION が無効であると大声で文句を言うべきです。そうすれば、ユーザーは何が起きているかを知ることができます (あなたと私の間では、整数に変換してバージョンが YYYYMMDD 形式のタイムスタンプであることを確認するのは少し簡単です)。

[私がコメントすることを許さないくそーIE6!いいえ、ブラウザを変更できません。企業に感謝します]

于 2008-09-16T10:25:53.557 に答える
0

これは予期された動作ではありません。これを lighthouse のバグとして報告することを提案するつもりでしたが、すでに報告されているようです。追加情報 (OS/データベース/Ruby バージョンなど) を提供していただければ、確認いたします。

于 2008-09-16T09:50:29.977 に答える