忍者ブログ
ブログツール、2007/11/06作成
[66] [65] [64] [63] [62] [61] [59] [58] [57] [56
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

テーブル関連、has_oneとかhas_manyとかの関連を持っているとき、
ついついActiveRecord::Base.destroyとかをオーバーライドしたくなるときがある。

例:

class Parent < AciveRecord::Base
  has_many :chidren, :dependent=>:destroy

  # 属性:deleted, :boolean, :default=>false

end

class Child < AciveRecord::Base
  belongs_to :parent

  # 属性:deleted, :boolean, :default=>false

end

親も子も関連する全員が@deletedがtrueになったときだけ全削除の実行に入る、
という必要があったとする。

親の方は簡単で、エイリアスを作ってオーバーライドすればいい。

class Parent < AciveRecord::Base
  has_many :children, :dependent=>:destroy

  alias :destroy! :destroy
 
  def  check_destory
    if # 自分と子が全員削除可能
      return self.destory!
    end
  end

  def destroy
    self.deleted = true
    return self.save
    retrun check_destroy
  end

end

てな感じ。

問題は子のほう。

メソッドを普通にオーバーライドすると、親の方が削除された時に、
自動的にdestoryが呼ばれるので無限ループに陥ってしまう。

で、苦肉の策で考えたのがこの方法。

class Child < ActiveRecord::Base
  belongs_to :parent
 
  def destroy
    if caller.to_s =~ /.+has_many_dependent_destroy_for_message_receiver_relations.+/
      return super
    else
      self.deleted = true
      self.save
      return self.parent.check_destroy
    end
  end

end

callerで呼び出し元をたどって、
そこにhas_many_dependent_destroy_for_message_receiver_relations
(関連で:dependent=>:destroyを設定したときに、自動で呼び出される)
が含まれていたら親が削除された一連の動作で削除されていると判断して、
superを呼び出し、
それ以外はフラグを設定してそこで処理を握りつぶすという方法。

これなら、親が削除されたとき以外は削除されずにすむ。

callerのチェックとかってあんまりやりたくないんだけど、
この方法ってなんか問題あるのかしら。

滅多に使わない方法なのでちょっと悩む。
てか、なんかほかのもっといい方法があったら教えてほしい。


PR
この記事にコメントする
name
title
color
mail
URL
comment
pass   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
secret (チェックを入れると管理人だけに表示できます)
この記事へのトラックバック
この記事にトラックバックする:
ついめ~じ
ブログ内検索
フリーエリア
サニーカメラ
Powered by Ninja Blog    template by Temp* factory    icon by MiniaureType

忍者ブログ [PR]