1. はじめに
Ruby on Rails 初心者で勉強しながら個人開発中
ActiveStorageで画像アップロード機能を実装後、本番環境で画像投稿したら、以下のエラーに遭遇しました。
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: relation "solid_queue_jobs" does not exist
開発環境
・Ruby 3.3.6
・Rails 8.0.2.1
・PostgreSQL
・Docker(開発環境)
・デプロイ: Render / Neon
2. このエラーについて
PG::UndefinedTable
は
「データベースに指定されたテーブルが存在しない」
というPostgreSQLのエラーを意味します。
今回は Rails 7.1以降で標準搭載された Solid Queue のsolid_queue_jobs
テーブルが作成されていなかったことが原因でした。
3. Solid Queueってそもそも何?
Rails 7.1 から標準で使えるようになった
バックグラウンドジョブ(非同期処理)を実行する仕組みです。
Rails には「Active Job」という“ジョブを定義する共通インターフェイス”があり、
その実行エンジン(バックエンド)として Solid Queue が標準採用されました。
何をしてくれるの?
たとえば、
- メール送信
- 画像のリサイズ
- 外部APIとの通信
など、時間のかかる処理を「あとで実行」するよう登録できます。
Solid Queue は、そのジョブをデータベース上のキューに登録し、
別のプロセス:Workerが順番に実行します。
4. 原因と解決までの手順
4-1. Solid Queueのマイグレーションが未実行の可能性
# webコンテナに入ってSolid Queueのマイグレーションを生成
docker compose exec web rails generate solid_queue:install
# 出力結果
identical config/queue.yml
identical config/recurring.yml
identical db/queue_schema.rb
identical bin/jobs
gsub config/environments/production.rb
# マイグレーションを実行してDBにテーブル作成
docker compose exec web rails db:migrate
既存の db/queue_schema.rb やマイグレーションファイルがあるため、新しいテーブルは作られませんでした。
そのため、すでに作られている状態ではマイグレーションを実行しても意味がありませんでした。
4-2. 本番環境の設定確認
4-2-1. データベース設定を統一
開発・本番環境で、 queue
データベースを含む複数DB構成に揃えました。
database.ymlの一部抜粋(クリックで展開)
# 開発環境
development:
primary: &primary_development
<<: *default
database: myapp_development
cache:
<<: *primary_development
database: myapp_development_cache
migrations_paths: db/cache_migrate
queue:
<<: *primary_development
database: myapp_development_queue
migrations_paths: db/queue_migrate
cable:
<<: *primary_development
database: myapp_development_cable
migrations_paths: db/cable_migrate
# 本番環境
production:
primary: &primary_production
<<: *default
url: <%= ENV['DATABASE_URL'] %>
cache:
<<: *primary_production
database: myapp_production_cache
migrations_paths: db/cache_migrate
queue:
<<: *primary_production
database: myapp_production_queue
migrations_paths: db/queue_migrate
cable:
<<: *primary_production
database: myapp_production_cable
migrations_paths: db/cable_migrate
4-2-2. Active Jobの設定
class Application < Rails::Application
# 既存の設定...
# SolidQueueの設定
config.active_job.queue_adapter = :solid_queue
config.solid_queue.connects_to = { database: { writing: :queue } }
end
4-2-3. Solid Queueの設定ファイルの確認
config/solid_queue.yml(クリックで展開)
default: &default
dispatchers:
- polling_interval: 1
batch_size: 500
workers:
- queues: "*"
threads: 3
processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %>
polling_interval: 0.1
development:
<<: *default
test:
<<: *default
production:
<<: *default
4-2-4.データーベース作成・マイグレーション
docker compose run --rm web rails db:create:all
docker compose run --rm web rails db:migrate
docker compose run --rm web rails db:migrate:cache
docker compose run --rm web rails db:migrate:queue
docker compose run --rm web rails db:migrate:cable
4-2-5. gemの確認
gem "solid_queue"
4-2-6. それ以外のデーターベース作成コマンド
docker-compose exec web rails generate solid_queue:install --force
色々試したけどエラーは変わりませんでした…
5 . これで解決!
docker-compose exec web rails db:schema:load SCHEMA=db/queue_schema.rb
ActiveRecord::Base.connection.tables.grep(/solid_queue/)
=>
["solid_queue_jobs",
"solid_queue_blocked_executions",
"solid_queue_claimed_executions",
"solid_queue_failed_executions",
"solid_queue_pauses",
"solid_queue_processes",
"solid_queue_recurring_executions",
"solid_queue_scheduled_executions",
"solid_queue_recurring_tasks",
"solid_queue_ready_executions",
"solid_queue_semaphores"]
注意
本番環境で db:schema:load を実行する場合、既存データが消える場合があります。必ずバックアップを取ってから実行してください。
6. なぜこの方法で動いたのか?
6-1. マイグレーションだけではダメな理由
- rails db:migrate は 「まだ実行していないマイグレーション」だけを反映
- すでにあるマイグレーションはスキップされる
- だから solid_queue_jobs テーブルは作られず、エラー発生
6-2. db:schema:load
- rails db:schema:load SCHEMA=db/queue_schema.rb は schema に書かれた完成形のテーブルを強制作成
- マイグレーションの状態に関係なく、一気に全テーブルを作れる
- これで solid_queue_jobs を含む Solid Queue 用テーブルが全部作られ、エラーが解消された
このあと、本番環境でも同じ手順をシェルスクリプトで実行して
# Gemのインストール
bundle install
# Solid Queueテーブルの存在確認・スキーマロード
SOLID_QUEUE_EXISTS=$(bundle exec rails runner "
begin
tables = ActiveRecord::Base.connection.tables.grep(/solid_queue/)
puts tables.size >= 10 ? 'true' : 'false'
rescue
puts 'false'
end
")
if [ "$SOLID_QUEUE_EXISTS" = "false" ]; then
DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rails db:schema:load SCHEMA=db/queue_schema.rb
fi
# データベースマイグレーション
bundle exec rails db:migrate
# アセット処理
bundle exec rails assets:precompile
bundle exec rails assets:clean
エラー解消となりました。
7. まとめ
Rails 8 以降の Solid Queue はまだ新しく、公式ドキュメントや記事も少ないため、初心者だと問題解決まで時間がかかりやすいです。
GitHub Issues でも同様の報告はいくつかありますが、初心者がそれらに辿り着くのは簡単ではありません。
そこで今回の記事では、そうした情報を整理し、解決までの手順をわかりやすくまとめました。
同じように悩んでいる人の参考になれば嬉しいです。
注意
環境や設定によっては他の原因も考えられるので、うまくいかない場合はログや設定を再確認してください。