簡體   English   中英

如何知道瑞克任務已經在軌道上運行?

[英]How to know that a rake task has been run in rails?

我在Rails應用程序中進行了遷移,僅當運行了特定的rake任務時,我才想運行它,否則會丟失大量數據。 以下是我想做的事情:

if has_rake_task_been_run?
  remove_column :transactions, :paid_by
end

目前,無論如何我都找不到,只能手動確保這一點。 有什么解決辦法嗎?

使用rake任務進行數據遷移是一個極具風險的想法。 不這樣做的幾個原因:

  1. 即使您設法找出您的rake任務是否已經完成,您的遷移仍將標記為已完成,並且您將無法重播它。 唯一的辦法就是在遷移中引發異常。

    不,您也將無法回滾該遷移。 如果運行遷移后rake任務完成,則回滾將嘗試添加已經存在的列。

  2. 新開發人員從頭開始建立數據庫將變得很痛苦,因為他們將需要知道什么時間運行哪些rake任務。 rake db:migrate執行所有遷移。

  3. 您正在用不可重復使用的任務污染耙任務列表

看來您正在做的只是定期的數據遷移,因此rake任務完成的所有工作實際上應該是遷移的一部分。 這甚至可以使您進行可逆的數據遷移(大多數情況下)。

但是請注意,數據遷移並不像常規的僅方案遷移那樣簡單。 因為您的遷移應該完全獨立於代碼(即使將來完全使用遷移模型,即使將來從代碼庫中完全刪除它們),所以重新定義要在遷移中使用的模型是一種慣例。 (只有遷移所需的位)。 聽起來很簡單,不幸的是,老實說,我仍在尋找完美的解決方案。 到目前為止,我所見過的最好的方法很簡單(我假設paid_by以前是字符串,而您將其更改為paid_by_id ,它引用了用戶):

class YOURMIGRATIONNAME < ActiveRecord::Migration
  class Transaction < ActiveRecord::Base
    belongs_to :paid_by, class_name: "User"
  end

  class User < ActiveRecord::Base
  end

  def up
    add_column :transaction, :paid_by_id, :integer

    Transaction.transaction do # for speed
      Transaction.find_each do |t|
        t.paid_by_id = User.find_by(username: t[:paid_by])
        t.save!         # Always banged save in migration!
      end
    end

    remove_column :paid_by
  end

  def down
    add_column :transaction, :paid_by, :string

    Transactions.transaction do 
      Transaction.find_each do |t|
        t[:paid_by] = t.paid_by && t.paid_by.username
        t.save!
      end
    end

    remove_column :transactions, :paid_by_id

end

使用上面的代碼的唯一缺點是,如果其中任何一個模型正在使用STI,它都將無法正常工作(我曾經犯過一次錯誤,花了一段時間才能找出問題所在)。 解決方法是在遷移類之外定義它,但是這些類在所有遷移中都可用,並且可能會受到實際模型代碼的影響(尤其是在預加載所有模型的情況下,在生產中)。 簡而言之,我目前仍在研究使用STI進行數據遷移。

萬一有人來了,我們成功地使用了after_party rails庫。 通過簡單的機制,該庫可以維護已執行的rake任務,並且可以輕松執行遷移任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM