Adequate Recordでキャッシュされないケースヘ(^o^)ノ

第65回 Ruby関西 勉強会に参加したよヘ(^o^)ノのつづき

スライドに、Adequate Recordでキャッシュされないケースを書いたけど、 ざっくりしすぎなのでまとめてみる( ˘ω˘)

find_byを例にactiverecordのコードを読みながら確認していく

コードはこんな感じ(コメントの*1とかは説明しやすいのでつけてるだけ)

# activerecord/lib/active_record/core.rb
def find_by(*args) # :nodoc:
  # *1  
  return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any?
  # *2  
  return super if default_scopes.any?

  hash = args.first

  # *3
  return super if hash.values.any? { |v|
    v.nil? || Array === v || Hash === v
  }

  # We can't cache Post.find_by(author: david) ...yet
  # *4  
  return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }

  ...
end

*1で判定していること

current_scopeがある

current_scopeでスコープがないことを確認してる

引数がHash以外

!(Hash === args.first)でチェックしてる

こんなのはキャッシュしてくれない

Post.find_by('created_at < ?', 1.weeks.ago)
composed_ofが設定されている

reflect_on_all_aggregations.any?でチェックしてる

設定されているだけでキャッシュしてくれない


*2で判定してること

default_scopeが設定されている

設定されているだけでキャッシュしてくれない


*3で判定していること

引数のハッシュ値(Value)がnil, Array,Hash

こんなのはキャッシュしない

Post.find_by(title: nil)
Post.find_by(title: ['ruby', 'rails'])
# Hashがくるケースが思い浮かばない...


*4で判定していること

Hashのキーにモデルのカラム以外が指定されている

以上の条件に当てはまる場合に、superすなわち本家のfind_byをよんでます

なので、単一テーブル継承(STI)やPolymorphicは、設定されているだけではキャッシュの対象外とはなりません

ここがややこしそうだ。。。

間違えてたら教えてくださいねー

Happy Hacking٩( ‘ω’ )و