ActiveJob::Arguments#serializeとは
ActiveJobの引数にActiveRecordオブジェクトのインスタンスを渡すと、それはシリアライズされずに、Global IDというURIに変換されます。
これを実現しているのが、ActiveJob::Arguments#serialize
とActiveJob::Arguments#deserialize
です。
例えば、
user = User.find(5)
SampleJob.perform_later(user)
とした場合、引数のuser
は、
serialized_args = ActiveJob::Arguments.serialize([user])
〜〜〜
略
〜〜〜
args = ActiveJob::Arguments.deserialize(serialized_args)
というような処理を挟むイメージです。
この時、上記のserialized_args
は、
[{"_aj_globalid"=>"gid://project_name/User/5"}]
のように、gid://アプリケーション名/モデル名/id
の形式で表現されます。
つまり、ActiveRecordのインスタンスをシリアライズせずに保持できるということです。シリアライズする必要がないので、容量を大きく節約することができます。
serializeをActiveJobの外で使う
最新のActiveJobではActiveJob::Arguments
はプライベートな内部モジュールとなっているため、ActiveJobの外で使うには明示的にrequire
する必要があります。
require 'active_job/arguments'
使用用途としては、何らかのメソッドに渡す引数・渡された引数を一時的に保存するのに使えそうです。
例えば、
def store_sample(*args)
key = SecureRandom.hex(12)
serialized_args = ActiveJob::Arguments.serialize(args)
Rails.cache.fetch(key.to_s) { serialized_args }
end
store_sample(User.find(4))
のようにローレベルキャッシュを利用することで、CacheStoreにstore_sample
メソッドに渡したActiveRecord型オブジェクトの引数を一時保存することも可能です(容量の問題を無視すれば、通常の方法でも可能ですが・・・)。
使ってみた
というわけで、ActiveJob::Arguments#serialize
の仕組みを利用した簡単なRails pluginを作ってみました。
EastResident/step_render
主な機能としては、部分テンプレート(partial)を遅延読み込みするというようなものです。