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)を遅延読み込みするというようなものです。