私は、未使用のリレーションをクリーンアップするために、HABTMリレーションシップを持つ複数のモデルに直接適用するメソッドを記述しようとしています。すべてのクラスのメソッドを書く方法
def cleanup self.all.each do |f| if f.videos.count == 0 self.destroy(f) end end end
どこにこのメソッドを保存するのですか?これは正しい構文ですか?
>>Tag.cleanup
私は、未使用のリレーションをクリーンアップするために、HABTMリレーションシップを持つ複数のモデルに直接適用するメソッドを記述しようとしています。すべてのクラスのメソッドを書く方法
def cleanup self.all.each do |f| if f.videos.count == 0 self.destroy(f) end end end
どこにこのメソッドを保存するのですか?これは正しい構文ですか?
>>Tag.cleanup
外部モジュールを書くと、あなたはあなたがタグのクラスにクラスメソッドを追加したい
を必要とする各モデルに含め、その代わりに、すべてのタグオブジェクトを繰り返すの:それは理論的として実行されるだろう(それぞれにレールをロードする必要があります)、Active Recordを使ってビデオをチェックすると、孤立したすべてのレコードをクエリでロードし、それらを破棄するほうが速くなります。あなたはここで、タグやビデオを持っている、そしてそのtag_videosがあなたの参加テーブルで、Railsの2.xの中で、あなたが
def self.cleanup
where("id NOT IN (select tag_id from tag_videos)").destroy_all
end
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
あなたはカウンターキャッシュ列を使用している場合は、多くのより簡単にこれを行うことができ、カウンタキャッシュが正確であることを保証する必要があります。
私は外部モジュールとしてこれを書いて使用しました。 にはMyMethodが含まれています しかし、まだそれを認識したくないようでした。 –
'include MyModule'の代わりに' extends MyModule'を使ってみてください。 - それぞれのインスタンスではなく、クラスにメソッドをアタッチする必要があります。 – dunedain289
正確なモジュールとモデルを表示する – fl00r