1
1

More than 3 years have passed since last update.

Rails6 のちょい足しな新機能を試す 127(memory cache編)

Posted at

はじめに

Rails 6 に追加された新機能を試す第127段。 今回は、memory cache 編です。
Rails 5.2.4.2 や、 Rails 6.0.0 では、 キャッシュとして、 memory cache を使っていて、 キャッシュから値を取り出したあとで、その値を破壊的メソッドなどで修正すると、 キャッシュの値も変わってしまうというバグ(?) がありました。

Rails 6.0.1 以降では修正されています。

Rails 6.0.2.2, Rails 6.0.1, Rails 6.0.0, Rails 5.2.4.2 で確認しました。

$ rails --version
Rails 6.0.2.2

今回は、 User モデルを作って cache を使って値を取り出すメソッドを作成して確認していきます。

Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

$ rails new rails_sandbox
$ cd rails_sandbox

User モデルを作成する

User モデルを作成します。

$ bin/rails g model User name

User モデルに cached_name メソッドを追加する

かなりわざとらしいですが、 User モデルに cached_name というメソッドを追加します。

cached_name では、 cache から name を取り出したあと、 upcase! で変換して、再度 cache から name を取り出します。

app/models/user.rb
class User < ApplicationRecord
  def cached_name
    name = Rails.cache.fetch("#{cache_key_with_version}/name") do
      User.find(id).name
    end
    name.upcase!
    Rails.cache.fetch("#{cache_key_with_version}/name") do
      User.find(id).name
    end
  end
end

スクリプトを作成する

User#cached_name を呼び出すスクリプトを作ります。

scripts/user_name.rb
User.delete_all
User.create(name: 'John')
u = User.last
p u.cached_name
p u.cached_name
p u.name

development 環境でキャッシュを有効にする

development 環境でキャッシュを有効にします。

$ bin/rails dev:cache
Development mode is now being cached.

Rails 6.0.1 以降では

スクリプトを実行すると名前は、常に John のままです。

$ bin/rails runner scripts/user_name.rb
Running via Spring preloader in process 675
"John"
"John"
"John"

Rails 6.0.0, Rails 5.2.4.2 では

キャッシュに保存されている値が変わってしまうため、2回目の cached_name の呼び出しのときに JOHN に変わってしまいます。

bash-5.0# bin/rails runner scripts/user_name.rb
Running via Spring preloader in process 747
"John"
"JOHN" # => キャッシュの値が変わっている
"John"

試したソース

参考情報

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1