YOSHINO日記

プログラミングに関すること

cattr_accessor(mattr_accessor)を使うべき時って?

3通りのアクセサについて

Rails: クラスレベルの3つのアクセサを比較する(翻訳)

  1. attr_accessor: 値を継承したくない場合に使う

  2. cattr_accessor(mattr_accessorのエイリアス): 値をすべてのクラスで共有したい場合に使う

  3. class_attribute: 継承した値を親クラスに影響を与えずに上書き可能にしたい場合に使う

この中でも2番めのmattr_accessorは、一番つかいどころが難しいように思います。

classで共通する変数を持つ時は基本的には、class_attributeを使うほうが良いと思います。

cattr_accessor(mattr_accessor)を使うべき時:Testの時にのみ値を変えたい場合

Ref

Switch to a single message verifier · rails/activestorage@8f20624 · GitHub

説明

上記の例では、

lib/active_storage.rb

mattr_accessor :verifier

lib/active_storage/engine.rb

ActiveStorage.verifier = Rails.application.message_verifier("ActiveStorage")

のようにクラス変数を定義しています。

そんなわけで、ActiveStorageを継承したクラスは上記の変数を利用することになります。

mattr_accessorで定義しているので、うっかり継承先クラスで値を書く変えてしまうことはあります。

実際に継承先で書き換えたい場合があるから、mattr_accessorしているのですが、今回の場合はテストケースでその値を全面的に書き換えたいからです。

以下のように変数の値をテストの時は上書きしています。

test/test_helper.rb

ActiveStorage.verifier = ActiveSupport::MessageVerifier.new("Testing")