lengthとcountとsize

今日のバッドノウハウ

AR::BaseのHasManyAssociationは子レコードの数を数えるメソッドとしてlengthとcountとsizeがあってそれぞれ動作が違います。
詳しくは某書(が出たら)を買ってほしいんですがw、これの動作は

  • countではカウンターキャッシュを使ってればそれを使って数を数えます
  • で、empty?もcount.zero?を使います。
  • fixutresを読み込むときはカウンターキャッシュのケアをしません(バグ? たぶん仕様)

つまり、fixutresを使ったテストのなかでparent.children.empty?と問い合わせると必ずtrueが返って来ます。

なのでfixturesを書くときにはちゃんとカウンターキャッシュのカラムも書きましょう。別解としてparent.children.length.zero?と処理するてもありますが、それは結局プロダクションのコードをテストのためにいじることになるので、やや悪手ですよね。*1 *2

*1:もちろん、以降の処理を見直した上で#lengthを使うのであればいいと思います

*2:length使う場合にもfixturesはちゃんと書きましょう、というのは変わらない