ActiveRecord で timestamp を更新せずに保存する


今回は小ネタです。

保存されたデータを更新したいが timestamp は更新したくないというケースがあると思います。
(何らかの外部の契機に応じてフラグを立てるとかデータを埋めるとか)

ActiveRecord の設定を変更してそもそも update 時に timestamp を更新しないようにすることもできるのですが、それはそれで通常の save のときに困ります。

そこで専用のメソッドをモデルに用意します。

class SomeModel
  def save_wo_timestamp
    class <<self
      def record_timestamps; false; end
    end

    begin
      self.save
    ensure
      class <<self
        remove_method :record_timestamps
      end
    end
  end
end

これで前述したような timestamp を更新したくない save ができるようになります。

s = SomeModel.find(100)
s.someone = "ほげ"
s.save_wo_timestamp # 時刻を更新せずに保存

よかったですね。

ちなみにこちらの記事を参考にしました。

あとあまり関係ないですがメタプログラミング Ruby は良書です。
実際にメタプログラミングをする機会はそれほど多くありませんが、 Ruby におけるメタプログラミングに触れるには大いに参考になると思います。

7/5 追記

Rails 5 では Model.save!(touch: false) とすることでタイムスタンプを更新せずに保存できます。簡単になりました。