Railsのconfigurationを調べてみた(5)
なに?
Railsのconfigurationはどんなものがあって、どういう挙動なのかを調べてみた。
今回調べたものはActiveRecordに含まれるconfigだけである。
# ActiveRecordに関するconfigurationは、以下のように`active_record`をはさむ。
config.active_record.cache_versioning = true
各項目の細かい挙動まで十分に調べきれてはいないが、よく設定する項目などは別途調べたい。
ばーじょん
- Ruby ruby 2.7.2p137
- Rails 6.1.2
いちらん
action_on_strict_loading_violation(symbol)
Rails6.1で導入されたStrict Loadingで、N+1を検知したときの挙動を指定する。
デフォルトは:raise
。
以下のサンプルコードを実行したときの挙動を見てみる。
# user = User.strict_loading.first
# user.posts.first
:raise
の場合は、以下のようなエラーが発生する。
ActiveRecord::StrictLoadingViolationError (`User` is marked for strict_loading. The `Post` association named `:posts` cannot be lazily loaded.):
app/controllers/dashboards_controller.rb:6:in `index'
:log
の場合は、以下のようなデバッグログだけを出力する。
Strict loading violation: User is marked for strict loading. The Post association named :posts cannot be lazily loaded.
belongs_to_required_by_default(boolean)
belongs_to
で設定したオブジェクトを、デフォルト必須にするかどうかを指定する。
デフォルトはfalse
。
ただし、5.0以降のデフォルト設定を読み込むとtrue
になる。
なお、個別に設定したい場合は、belongs_to :hoge, optional: true
と指定すればよい。
cache_timestamp_format(symbol)
キャッシュのキーを生成するときの時間フォーマットを指定する。
デフォルトは:usec
。
指定できるsymbolは、以下を参照。
一覧に設定したいフォーマットがない場合は、以下のように追加することも可能。
# config/initializers/time_formats.rb
Time::DATE_FORMATS[:month_and_year] = '%B %Y'
cache_versioning(boolean)
キャッシュのキーに、バージョン情報を含めるかを指定する。
デフォルトはfalse
。
ただし、5.2以降のデフォルト設定を読み込むとtrue
になる。
通常updated_at
を用いてバージョン情報を付加するのだが、更新するたびに新しいキーが生成されてしまうため、キャッシュストアの容量を圧迫してしまうことを懸念したようだ。
true, false
の挙動の違いは、以下の通り。
# true
irb(main):001:0> user = User.first
irb(main):002:0> user.cache_key
=> "users/1"
irb(main):003:0> user.cache_version
=> "20210220004037981030"
irb(main):004:0> user.cache_key_with_version
=> "users/1-20210220004037981030"
# false
irb(main):001:0> user = User.first
irb(main):002:0> user.cache_key
=> "users/1-20210220004037981030"
irb(main):003:0> user.cache_version
=> nil
irb(main):004:0> user.cache_key_with_version
=> "users/1-20210220004037981030"
check_schema_cache_dump_version(boolean)
schema_cache.ymlとの整合性をチェックするかを指定する。
デフォルトはtrue
。
schema_cache.ymlについては、use_schema_cache_dump
の項目で説明する。
schema_cache.ymlとDBの状態にズレがある場合は、以下のようなwarningログが出力される。
Ignoring /home/kehra/Develop/rails-sample/db/schema_cache.yml because it has expired. The current schema version is 20210217232526, but the one in the cache is 20210217232525.
collection_cache_versioning
cache_versioning
のQueryバージョン。
デフォルトはfalse
。
ただし、6.0以降のデフォルト設定を読み込むとtrue
になる。
挙動は以下のようになる。
irb(main):002:0> User.where(id: 1..).cache_key
(0.4ms) SELECT COUNT(*) AS "size", MAX("users"."updated_at") AS timestamp FROM "users" WHERE "users"."id" >= ? [["id", 1]]
=> "users/query-b7585bc163fa97756ce4e06aa0ca1bc6"
database_resolver(class)
データベースの接続先を決めるResolverクラスを指定する。
デフォルトはActiveRecord::Middleware::DatabaseSelector::Resolver
。
デフォルトのResolverは、Primaryのread/writeとReplicaのreadの3種類をSQLや発行タイミングを見て切り替えている。
database_resolver_context(class)
database_resolver
に渡すコンテキストを指定する。
デフォルトはActiveRecord::Middleware::DatabaseSelector::Resolver::Session
。
database_selector(hash)
database_resolver
に渡すオプションを指定する。
デフォルトは未設定。
詳しくは、Rails Guideを参照。
default_connection_handler(class)
データベースのコネクションを管理するHandlerを指定する。
デフォルトはConnectionAdapters::ConnectionHandler.new
。
default_role(symbol)
接続先のデフォルトのロールを指定する。
デフォルトはconfig.active_record.writing_role
の値が設定される。
default_shard(symbol)
接続先のデフォルトのシャードを指定する。
デフォルトは:default
。
default_timezone(symbol)
接続時のtimezoneを指定する。
デフォルトは:utc
。
destroy_association_async_job(class)
dependent: :destroy_async
を指定したときの削除ジョブを指定する。
デフォルトはActiveRecord::DestroyAssociationAsyncJob
。
dump_schemas(symbol, string)
db:structure:dump
タスクを実行したときの動作を指定する。
デフォルトは:schema_search_path
。
なお、本オプションはPostgreSQLでのみ利用可能である。
dump_schema_after_migration(boolean)
マイグレーションを実行したあとに、スキーマをダンプするかを指定する。
デフォルトはtrue
。
error_on_ignored_order(boolean)
ApplicationRecord.in_batches
を実行したときに、ApplicationRecord.order
が設定されたときの挙動を指定する。
デフォルトはfalse
。
これは、ApplicationRecord.in_batches
を実行したときに、強制的にorder(#{primary_key})
が設定されるためで、意図しない挙動を通知するための仕組みである。
true
の場合は、以下のようなエラーが発生する。
ArgumentError (Scoped order is ignored, it's forced to be batch order.):
app/controllers/dashboards_controller.rb:5:in `map'
app/controllers/dashboards_controller.rb:5:in `index'
false
の場合は、以下のようなwarningログだけを出力する。
Scoped order is ignored, it's forced to be batch order.
has_many_inversing(boolean)
inverse_of
を設定したときに、意図しない挙動が行ってしまうバグがあったが、挙動が大きく変わってしまうため、オプションとなったようだ。
デフォルトはfalse
で修正前の挙動となる。
ただし、6.1以降のデフォルト設定を読み込むとtrue
になる。
どういうバグなのかを検証できなかったので、該当PRを記載しておく。
legacy_connection_handling(boolean)
データベースコネクションのハンドリングを従来の挙動にするかを指定する。
デフォルトはtrue
。
ただし、6.1以降のデフォルト設定を読み込むとfalse
になる。
false
にすると、抽象クラスでのハンドリングが可能となる。
logger(class)
ロガークラスを指定する。
デフォルトはRails.logger
が設定される。
maintain_test_schema(boolean)
テスト実行時に、マイグレーション情報との差分をチェックするかを指定する。
デフォルトはtrue
。
true
で差分があった場合、db:test:prepare
タスクを実行して、自動的に最新の状態に合わせようとする。
migration_error(symbol)
マイグレーション情報に差分があったときの挙動を指定する。
デフォルトは:page_load
。
:page_load
を指定した場合、リクエストのたびにマイグレーション情報をチェックし、差分を検知したらActiveRecord::PendingMigrationError
をraiseする。
queues(object)
非同期ジョブのキューを詰めるオブジェクトを指定する。
デフォルトはActiveSupport::InheritableOptions.new
。
schema_format(symbol)
スキーマ情報をどういう形式で出力するかを指定する。
デフォルトは:ruby
。
:sql
を指定することも可能だが、ミドルウェアを変更する際に注意が必要。
strict_loading_by_default(boolean)
Rails6.1で導入されたStrict Loadingを全体で適用するかどうかを指定する。
デフォルトはfalse
。
個別に指定する場合は、.strict_loading
を呼び出す。
suppress_multiple_database_warning(boolean)
database.ymlが正しく読み込めなかったときのエラーを抑制するかどうかを指定する。
デフォルトはfalse
。
use_schema_cache_dump(boolean)
スキーマのキャッシュを使うかどうかを指定する。
デフォルトはtrue
だが、キャッシュファイルが見つからない場合は、スキップされる。
スキーマのdumpは、db:schema:cache:dump
タスクで行い、db/schema_cache.yml
が生成される。
これにより、データベースにスキーマ情報を問い合わせなくてもよくなる。
timestamped_migrations(boolean)
マイグレーションファイルを作成するときに、timestampを付加するかどうかを指定する。
デフォルトはtrue
。
false
にすると、前のマイグレーションファイルの番号をインクリメントした番号を付加する。
verbose_query_logs(boolean)
クエリーがどこで設定されていたのかをdebugログに出力するかを指定する。
デフォルトはfalse
。
true
にした場合、以下のようなログが出力される。
Post Load (0.3ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT ? [["LIMIT", 1]]
↳ app/controllers/dashboards_controller.rb:7:in `index'
warn_on_records_fetched_greater_than(integer)
レコードをfetchしたとき、warningをだす件数を指定する。
デフォルトは未設定。
指定した件数を超えたとき、以下のようなwarningログが出力される。
Query fetched 2 Post records: PRAGMA foreign_keys = ON;SELECT sqlite_version(*);SELECT "posts".* FROM "posts"
Discussion