4

データベースにレコードを作成し、無期限に実行できる rake タスクを作成しています。このタスクの 1 つの側面は、モデル間の多対多の関連付けを作成することです。結合テーブルにエントリを追加しているときにタスクを終了すると、そのモデルの関連付けが完了しません。タスクのコードは次のとおりです。

(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 を実行するとロールバックするトランザクションでこれらすべてをラップするにはどうすればよいでしょうか。または、関連する次のアイテムに移動する代わりに、ループを終了し、ステージを更新してから終了します。

4

1 に答える 1

15

transactionブロックを使用して、トランザクション内に物事をラップできます。例として:

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

に到達しない場合、endSQLCOMMITは適用されません。つまり、上記の関係は作成されません。

のようなものも使用できますがItemRelation.transaction、トランザクションはモデル固有ではないため、同じように機能することに注意してください。

詳細については、アクティブ レコード トランザクションページを参照してください。

Ctrl+C を受け取った後、待って何かを終わらせる方法はありません。トランザクションベースのアプローチが最適です。

于 2012-04-28T23:23:24.590 に答える