QA@IT

[rails]チェックボックスによってDELETEのSQLが発行されたときのコールバックの取得方法

1804 PV

表題の件、知見のある方ご指導いただきたく質問いたしました。

環境
Ruby2.1.2 / Rails4.1.6
PostgreSQL9.3

現状

  • Shop <-> ShopItem <-> Item という関連でテーブルを持っている。
  • ShopItemテーブルにはacts_as_listを使うためにpositionカラムがある(shop_idごとに順番保持)。
  • Itemが削除された場合、すでにShopItemにある同じitem_idのデータもDELETEされる。
  • DELETEされた結果、positionが(shop_idごとに)連続した値にならないことがある(2番と3番を削除したら、position=1,4,5...になる)

やりたいこと

  • DELETEが実行されたタイミングでpositionの値を1から振りなおす。
  • 並べ替えを「▲」「▼」 ボタンで行っており、1番目が消されるとitem.first?などで判定ができずに先頭データでも「▲」が表示されてしまうのを防ぎたい(最終手段でCSSのli:first-childとかで非表示にする?)。

しかしafter_destroyではコールバックを呼び出せませんでした。after_saveなどでItemが追加された場合は呼び出せました。
何かよい対応方法が思いつく方、いらっしゃいましたらアドバイスいただけると幸いです。

よろしくお願いいたします。

補足

更新時に送信されるパラメタ例。
下記例だと、ShopItem.item_id が 2と3以外は、そのレコードをDELETEするようです(shop_id毎)。

Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxx", "shop"=>{"item_ids"=>["2", "3", ""], "commit"=>"更新"}

回答

act_as_listを使った事が無いので削除部分がどうなっているかわかりませんが

しかしafter_destroyではコールバックを呼び出せませんでした。

deleteで削除している場合はafter_destroyは呼び出されません。
destroyで削除する事が可能なら呼び出されるかもしれません。

別の対処方法で(グループごとのpositionを利用させるための)scopeを使って対処する方法もあるようです
以下は論理削除の例ですが、論理削除時に存在判断用の列にnil以外を設定し、scopeにその列を利用した条件を設定しておく方法が以下のサイトで紹介されていました。

http://blog.keit.me/20130123/142/

deleted_at列を用意しておき

acts_as_list :scope => 'deleted_at is NULL'

この状態で、論理削除時にdeleted_at列にNULL以外を設定する。
というものです。

編集 履歴 (0)
  • ご回答ありがとうございます!

    updateメソッドを実行しており、明示的にdestroy / deleteで削除はしていません。だからafter_destroyでは呼び出せないのか、と思いました。説明不足で申し訳ございません。

    deleted_atを使う方法は、なるほどですね。削除の度に不要レコードが蓄積していくので若干抵抗がありますが。。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。