Rails4.2 直接SQLのupdate文で更新した結果がレコードセットに乗らないケース

ActiveRecordのキャッシュが原因。

コントローラ内で下記のようなコードを続けて書いて実行する。

 

其の一:findでレコードを取得する

其の二:同じレコードの内容を更新するSQLのupdate文を書いてexecuteする

其の三:其の一と同じコードで、同じレコードを取得する

 

其の三で再取得しているので、最新の内容が返ってくると思ったら大間違い。

Railsは其の一でクエリーをキャッシュする。次に同じクエリーになる場合はDBに問い合わせずキャッシュした値が返る。save等を使って更新するとキャッシュがクリアされるので、次回は最新の内容が返ってくる。またキャッシュされてその繰り返し。通常はそーやって成り立っているが、其の二でSQL文を書いているので、キャッシュがクリアされず、其の三では其の一でキャッシュした値が返る。

 

SQL文を書いているのはそれなりに理由があるのでやめたくはない。

 

uncachedでキャッシュさせないことができる。

個別にuncachedするより、ブロック(範囲)指定できるのでブロック指定で解決した。

 

  ActiveRecord::Base.uncached {
    # ここに其の一から其の三まで入れた
  }