2012-04-28 50 views
3

我正在寫一個rake任務,該任務在我的數據庫中創建記錄,並且可以運行無限期的時間。該任務的一個方面是在模型之間建立多對多關聯。如果我要在向連接表添加條目時退出該任務,則無法完成與該模型相關的任務。這裏是從任務的一些代碼:如何在Rake任務中使用ActiveRecord事務以在Ctrl + C中斷的情況下回滾

(1..100).each do |page| 

    related = Nokogiri::HTML(open(url + "item/#{item.id}/related/#{page}")) 

    related.css('.box').each do |box| 
     id = box.css('a').first.attr(:href).scan(/\/(\d+)\//)[0][0].to_i 
     title = box.css('p.title a').text 
     related_item = Item.create :title => title, :foreign_id => id 
     ItemRelation.create :item => item, :related_item => related_item 
    end 

end 

item.update_attributes :stage => ItemStage::RELATED 

在這裏我遍歷相關項目的所有頁面和當前項目之間創建一個ItemRelation(這個循環是另一種循環,它遍歷裏面的物品,這是那裏的'item'變量來自)。以及我通過抓取這些網頁所獲得的所有相關項目。

如果我要在迭代這些頁面的同時退出程序,則當前項目不會完成相關操作,並且階段在最後不會更新。

那麼,如何包裝這一切都在一個事務中,當我做按Ctrl + C,將回滾,否則將完成循環,更新的階段,然後退出,而不是去到下一個項目涉及

回答

11

您可以使用transaction塊將事物包裝在交易中。舉個例子:

ActiveRecord::Base.transaction do 
    # create relation 1 
    # create relation 2 
    # Ctrl+C 
    # create relation 3 
end 

如果未達到end,那麼SQL COMMIT將不會被應用,這意味着沒有任何關係,上述將被創建。

值得注意的是,您也可以使用類似ItemRelation.transaction之類的東西,但交易不是特定於模型的,因此它的工作原理相同。

更多信息可在Active Record Transactions頁面找到。

接收到Ctrl + C後,沒有辦法等待並關閉某些東西;基於交易的方法是一條路。

相關問題