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にあたるまで廃棄してくってんじゃだめかなぁ。
(試してない)