STIでのトラブル
acts_as_cachedは便利だが、モデルで継承(STI)を使っている場合、扱いに注意必要。
たとえば、
class RealEstate < ActiveRecord::Base acts_as_cached end class Land < RealEstate end class Building < RealEstate end
ってモデルがあって、
# インスタンス生成 Land.create(...) # => <Land:0xb71fa45c @attributes={"id"=>"1", "type" => "Land", ...}> # 取得(キャッシュ) Land.get_cache(1) # => <Land:0xb71f4e44 @attributes={"id"=>"1", "type" => "Land", ...}> # ためしにBuildingから探してみるが無論エラー Building.find(1) # => ActiveRecord::RecordNotFound: Couldn't find Building with ID=1 # キャッシュを取得できてしまう Building.get_cache(1) # => <Land:0xb71dc524 @attributes={"id"=>"1", "type" => "Land", ...}>
これは、キャッシュのキーを求める際に、以下のように基底クラスの名前を使ってるため。
つまり、Land.get_cache()でも、Building.get_cache()でも、RealEstate.get_cache()でも同じキャッシュを参照するようになっているわけだ。
サブクラスで別にキャッシュしてると、例えばLandインスタンスを変更した際、RealEstateでのキャッシュは破棄されないからかな。あと、Land.get_cache(1)が呼び出された時点で、RealEstate.get_cache(1)でも使えるってのは効率的だし。
module ClassMethods def cache_class_name @cache_class_name ||= respond_to?(:base_class) ? base_class.name : name end end
個々にキャッシュしておいて、再帰的にsuperを呼び出してbase_classにあたるまで廃棄してくってんじゃだめかなぁ。
(試してない)