我正在嘗試編寫一個方法,該方法將直接應用於具有HABTM關係的幾個模型以清理所有未使用的關係。如何爲所有類編寫方法
def cleanup self.all.each do |f| if f.videos.count == 0 self.destroy(f) end end end
我在哪裏可以保存這個方法,並且這個方法甚至是正確的語法?每個模型需要
我正在嘗試編寫一個方法,該方法將直接應用於具有HABTM關係的幾個模型以清理所有未使用的關係。如何爲所有類編寫方法
def cleanup self.all.each do |f| if f.videos.count == 0 self.destroy(f) end end end
我在哪裏可以保存這個方法,並且這個方法甚至是正確的語法?每個模型需要
寫入外部模塊,包括它:它理論上可以運行爲(需要導軌加載每一個),然後通過Active Record檢查視頻,使用查詢加載所有孤立記錄的速度更快,然後僅銷燬這些記錄。
猜你有標記和視頻,在這裏,而且tag_videos是你的連接表,在Rails的2.X你可以寫
def self.cleanup
find(:all, :conditions => "id NOT IN (select tag_id from tag_videos)").destroy_all
end
在Rails 3,你會寫
def self.cleanup
where("id NOT IN (select tag_id from tag_videos)").destroy_all
end
你想一個類的方法添加到標籤類,並且,而不是通過所有標籤對象迭代
>>Tag.cleanup
可悲的是,人們繼續使用has_and_belongs_to_many
,即使它會導致這樣的孤兒。 has_many ..., :through
關係可以被標記爲:dependent => :destroy
以自動清理未使用的孩子。通常情況下,您會有未使用的連接記錄,並且它們令人討厭地被刪除。
你可能要做的是從SQL角度來解決這個問題,因爲如果他們的父記錄不再被定義,has_and_belongs_to_many
記錄將無法訪問。就ActiveRecord而言,它們根本就不存在。使用連接模型意味着您可以隨時訪問這些數據,因爲它們都是自己的ID。
has_and_belongs_to_many
關係是基於一個複合關鍵字,它使得它們成爲一個嚴重的麻煩。通常你會做DELETE FROM table WHERE id IN (...) AND ...
,並確信只有目標記錄被刪除。用複合鍵你不能做到這一點。
你會發現這個工程的一個例子標籤項關係:
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
的DELETE
說法可真講究,它如何運作,不給同一緯度的SELECT
與加入,可以是根據需要定義爲左側或右側,內側或外側。
如果你有你的加入表中的主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
如果使用計數器緩存列,您可以更輕鬆地這樣做了很多,但你也必須確保你的計數器緩存是準確的。
我沒有寫這個作爲外部模塊,然後使用 包括我的方法 但它似乎並不想認出它仍然。 –
嘗試使用'擴展MyModule'而不是'include MyModule' - 應該將方法附加到類而不是每個實例。 – dunedain289
顯示您的確切模塊和您的模型 – fl00r