简体   繁体   中英

How do I use an ActiveRecord Transaction in a Rake Task to rollback in the case of a Ctrl+C interrupt

I'm writing a rake task that creates records in my database and can run for an indefinite amount of time. one aspect of the task is creating many-to-many associations between models. If I were to quit the task while it's adding entries to a join table it wouldn't finish relating that model. here's some code from the task:

(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

Here I'm iterating over all the pages of related items and creating an ItemRelation between the current item (this loop is inside another loop that loops over items, this is where the 'item' variable is from). and all the related items I get from scraping these pages.

If I were to exit the program while iterating over these pages the current item would not be completed related and the stage wouldn't be updated at the end.

So how can I wrap all this in a transaction that will rollback when I do Ctrl+C, or it will finish the loop, update the stage, and then exit instead of going to the next item to relate

You can wrap things within a transaction using a transaction block. As an example:

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

If the end is not reached, then SQL COMMIT will not be applied, meaning that none of the relations above will be created.

It's worth noting that you can use something like ItemRelation.transaction , too, but transactions are not model-specific, so it works out the same.

More information can be found on the Active Record Transactions page.

There's no way of waiting and finishing something off after receiving Ctrl+C; a transaction-based approach is the way to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM