※この記事はClaudeCodeを利用して実装した際にハマったことを、ClaudeCodeにブログ記事を書いてもらっています。
はじめに
Docker + Rails 環境で RSpec のテストを実行していたら、なぜか config/environments/test.rb の設定が効いていないという問題に遭遇しました。
原因を調査した結果、docker-compose.yml で設定した環境変数と rails_helper.rb の ||= 演算子の組み合わせが原因でした。
この記事では、問題の原因と解決方法を共有します。
問題の状況
症状
- Request specs で
403 Forbiddenエラーが発生 config/environments/test.rbで設定したconfig.hosts.clearが効いていない- ローカルでは動くのに、なぜか設定が反映されない 調査 デバッグ用のコードを入れて確認したところ、テストを実行しているはずなのに、RAILS_ENV が development になっていた。
# テスト内で確認
puts "RAILS_ENV: #{Rails.env}"
# => RAILS_ENV: development # !?
原因
docker-compose.yml の設定
# docker-compose.yml
services:
web:
environment:
- RAILS_ENV=development # ← これが原因!
- DATABASE_HOST=db
開発用に RAILS_ENV=development を設定していました。
rails_helper.rb の設定
# spec/rails_helper.rb
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test' # ← ||= は既存の値を上書きしない
require_relative '../config/environment'
||= 演算子は「左辺が nil または false の場合のみ右辺を代入する」という動作をします。
つまり、docker-compose.yml で RAILS_ENV=development が既に設定されているため、||= 'test' は何もしません。
結果
docker-compose.yml: RAILS_ENV=development
↓
rails_helper.rb: ENV['RAILS_ENV'] ||= 'test' # 何もしない
↓
実際の環境: development
↓
config/environments/test.rb は読み込まれない!
解決方法
||= を = に変更して、強制的に test を設定するようにしました。
# spec/rails_helper.rb(修正後)
require 'spec_helper'
# Docker 環境では RAILS_ENV=development が設定されているため、強制的に上書き
ENV['RAILS_ENV'] = 'test'
require_relative '../config/environment'
別の解決方法
方法1: docker-compose.yml から RAILS_ENV を削除
# docker-compose.yml
services:
web:
environment:
# - RAILS_ENV=development # 削除
- DATABASE_HOST=db
Rails はデフォルトで development を使うため、明示的に設定する必要はありません。
方法2: テスト実行時に環境変数を指定
docker-compose exec -e RAILS_ENV=test web bundle exec rspec
ただし、毎回指定するのは面倒なので、rails_helper.rb での強制上書きがおすすめです。
教訓
||=の動作を理解する: 既存の値がある場合は上書きしない- Docker 環境での環境変数を確認する:
docker-compose.ymlで何が設定されているか 把握する - 設定が効かない時は基本を疑う: 複雑な原因を探す前に、環境変数などの基本的な設定 を確認する まとめ 今回の問題は、Docker の環境変数設定と Ruby の
||=演算子の組み合わせによる意図しない動作でした。 「設定ファイルを修正したのに効かない」という時は、そもそも正しい環境で動いているかを最初に確認することが大切です。