2011-02-22 8 views
1

私は、未使用のリレーションをクリーンアップするために、HABTMリレーションシップを持つ複数のモデルに直接適用するメソッドを記述しようとしています。すべてのクラスのメソッドを書く方法

 
    def cleanup 
     self.all.each do |f| 
      if f.videos.count == 0 
       self.destroy(f) 
      end 
     end 
    end 

どこにこのメソッドを保存するのですか?これは正しい構文ですか?

 
    >>Tag.cleanup 

答えて

4

外部モジュールを書くと、あなたはあなたがタグのクラスにクラスメソッドを追加したい

+0

私は外部モジュールとしてこれを書いて使用しました。 にはMyMethodが含まれています しかし、まだそれを認識したくないようでした。 –

+1

'include MyModule'の代わりに' extends MyModule'を使ってみてください。 - それぞれのインスタンスではなく、クラスにメソッドをアタッチする必要があります。 – dunedain289

+0

正確なモジュールとモデルを表示する – fl00r

1

を必要とする各モデルに含め、その代わりに、すべてのタグオブジェクトを繰り返すの:それは理論的として実行されるだろう(それぞれにレールをロードする必要があります)、Active Recordを使ってビデオをチェックすると、孤立したすべてのレコードをクエリでロードし、それらを破棄するほうが速くなります。あなたはここで、タグやビデオを持っている、そしてそのtag_videosがあなたの参加テーブルで、Railsの2.xの中で、あなたが

def self.cleanup 
    where("id NOT IN (select tag_id from tag_videos)").destroy_all 
end 
2
を書きたいのRails 3では

def self.cleanup 
    find(:all, :conditions => "id NOT IN (select tag_id from tag_videos)").destroy_all 
end 

を書くかもしれないと推測

悲しいことに、このような孤児のすべての種類につながるにもかかわらず、has_and_belongs_to_manyを使用し続けます。 has_many ..., :throughの関係には:dependent => :destroyというフラグを立てて、未使用の子を自動的にクリーンアップすることができます。使用されていない参加記録があり、削除するのは面倒です。

親レコードが定義されていない場合、has_and_belongs_to_manyレコードにアクセスできないため、これはSQLの角度からアプローチします。 ActiveRecordに関する限り、それらは単に存在しません。結合モデルを使用すると、独自のIDが発行されるため、いつでもこのデータにアクセスできます。

has_and_belongs_to_manyリレーションシップは、重大な迷惑を除去する複合キーに基づいています。通常はDELETE FROM table WHERE id IN (...) AND ...を実行し、ターゲットレコードのみが削除されると確信します。複合キーではこれを行うことはできません。 DELETE文は、それが動作し、それができ合流してSELECTと同じ緯度を与えるものではありませんかについては本当に特別なことができ

DELETE FROM item_tags, tags, items WHERE item_tags.tag_id=tags.id AND item_tags.item_id=items.id AND tags.id IS NULL AND items.id IS NULL 

:あなたはこれを見つけることが

は、アイテムの関係に例のタグのために働きます必要に応じて左または右、内側または外側として定義される。

あなたは簡単にそれを行うことができ、あなたの参加テーブルのプライマリIDキーがあった場合:

DELETE FROM item_tags WHERE id IN (SELECT id FROM item_tags LEFT JOIN tags ON item_tags.tag_id=tags.id LEFT JOIN items ON item_tags.item_id=items.id WHERE tags.id IS NULL AND items.id IS NULL) 

は、実際には、ActiveRecordのは、それを無視しても、あなたの関係のテーブルに主キーを追加することが有利かもしれませんが。

編集:あなたのモジュールの問題については

、あなたがそのアプローチで立ち往生している場合:

module CleanupMethods 
    def cleanup 
    # ... 
    end 
end 

class Tag 
    # Import the module methods as class methods 
    extend CleanupMethods 
end 

あなたはカウンターキャッシュ列を使用している場合は、多くのより簡単にこれを行うことができ、カウンタキャッシュが正確であることを保証する必要があります。

関連する問題