1

移行は本番環境では失敗しますが、開発では期待どおりに実行されました。

...                                                               # everything to
20120709174326_add_subject_to_campaigns.rb                        # here runs fine.
20120711001125_set_default_value_for_publishable_in_newsletter.rb # <- this fails.
20120711010818_set_default_value_for_publishable_in_contents.rb
20120711010855_set_default_value_for_published_in_editions.rb
20120711191427_add_newsletter_date_to_newsletters.rb
20120711194230_rename_cm_campaign_sent_at_in_campaigns.rb

移行エラーは次のようになります。

-bash> heroku run rake db:migrate --remote staging
Running rake db:migrate attached to terminal... up, run.1
==  SetDefaultValueForPublishableInNewsletter: migrating ======================
-- change_column(:newsletters, :publishable, :boolean, {:default=>false})
   -> 0.1554s
rake aborted!
An error has occurred, this and all later migrations canceled:

undefined method `newsletter_date' for #<Newsletter:0x00000005961bd0>

問題は、newsletter_dateが後で追加されるまで追加されないのに、なぜそれが失敗する/すぐに言及するのですか?開発では完全に正常に動作しました。

4

1 に答える 1

1

失敗した移行(20120711001125_set_default_value_for_publishable_in_newsletter.rb)..。

def up
  change_column :newsletters, :publishable, :boolean, default: false
  Newsletter.scoped.where('publishable is NULL').each do |n|
    n.publishable = false
    n.save
  end
end

...モデル Newsletterを使用し、保存する前に検証を実行します(具体的には、のpresence検証newsletter_date)...

validates :newsletter_date, presence: true

...しかし、それ(列)は後で追加されるまで(-上記のリストの最後から2番目の移行) newsletter_date、まだ存在していません。newsletter_date20120711191427_add_newsletter_date_to_newsletters.rb

class AddNewsletterDateToNewsletters < ActiveRecord::Migration
  def change
    add_column :newsletters, :newsletter_date, :date
  end
end

解決策は次のとおりです。(1)開発中、移行を失敗する前の移行にロールバックします。(2)列を追加する移行の名前を変更し、失敗した移行の直前にタイムスタンプを変更します。(3)移行を実行します。(4)gitを更新します。(5)Herokuにプッシュします。(6)本番環境では、移行を実行します。(7)Herokuプロセスを再起動します。

bundle exec rake db:rollback # five times in this case
mv db/migrate/20120711191427_add_newsletter_date_to_newsletters.rb db/migrate/20120711001025_add_newsletter_date_to_newsletters.rb
bundle exec rake db:migrate
git add db/migrate/20120711001025_add_newsletter_date_to_newsletters.rb
git rm db/migrate/20120711191427_add_newsletter_date_to_newsletters.rb
git commit -m "changed migration timestamp to fix migration order issue"
git push staging master
heroku run rake db:migrate --remote staging
heroku restart --remote staging

開発で機能した理由は、テーブルのpublishable列のデフォルト値を設定する移行が実行された時点では、列とモデルの検証がまだ存在していなかったため、問題はありませんでした。すべてが本番環境に移行するまでに、最新のコードによってメソッドと関連する検証が実現しましたが、移行はタイムスタンプ順に既存のコードで実行されるため、データベースの準備よりも新しいコードが存在する可能性があります。newslettersnewsletter_datenewsletter_date

于 2012-07-18T21:37:11.087 に答える