はじめに
先日、本番環境で一度きりのデータ更新が必要になりました。
具体的には「あるレコードの特定のカラムをfalse
からtrue
に更新したい」というケースでした。
これを実現する方法として以下のような選択肢がパッと思い浮かびました。
- Railsコンソールで手動実行
- Rakeタスクの作成
- 新しいコマンドの作成
しかし、1回きりの実行のために新しいタスクやコマンドを作るのは大げさです。
かといってコンソールでの手動実行はミスが怖くてやりたくありません。
そうした中でrails runner
コマンドの存在を知ったため、備忘録としてまとめます。
rails runner
コマンドとは
rails runner
はRailsの環境を読み込んだ状態でRubyのスクリプトを実行できるコマンドです。
以下のシンプルなコマンドさえ叩けば、追加の設定や定義はせずにスクリプトを実行できます。
$ rails runner path/to/your_script.rb
実際の使用例
まず、以下のようなRubyのスクリプトを作成しました。
scripts/update_user_verified.rb
# 更新対象のユーザーを取得
target_user = User.find_by!(name: '佐藤二郎')
puts "#{target_user.name} (認証: #{target_user.verified})"
if ENV['DRY_RUN']
puts "確認モードのため、実際の更新は行いません"
else
target_user.update!(verified: true)
end
puts "#{target_user.name} (認証: #{target_user.verified})"
そして次のように実行します。
# 確認実行(どのレコードが更新対象かを確認)
$ DRY_RUN=1 rails runner scripts/update_user_verified.rb
佐藤二郎 (認証: false)
確認モードのため、実際の更新は行いません
佐藤二郎 (認証: false)
# 本番実行(実際にデータを更新)
$ rails runner scripts/update_user_verified.rb
佐藤二郎 (認証: false)
更新を行います
佐藤二郎 (認証: true)
なぜrails runner
コマンドが良かったか?
rails runner
はRakeタスクと比べて次の点で良いと思いました。
1. ファイル配置が自由
- Rakeタスク:
lib/tasks
ディレクトリに.rake
ファイルを作成する必要がある -
rails runner
: 任意のディレクトリに.rb
ファイルを配置してOK
2. コードの書き方が自由
- Rakeタスク:
namespace
,task
,desc
などの定型文が必要 -
rails runner
: 純粋なRubyプログラムとして書いてOK
3. 一時的なスクリプトだと明示できる
- Rakeタスク: 恒久的なタスクとして
lib/tasks
に残り続ける -
rails runner
:scripts
ディレクトリに配置するなどして、一時的な用途であることを明確にできる
おわりに
1回きりのデータ更新にはrails runner
がとても便利だと分かりました。
Rakeタスクほどの本格的な実装は必要なく、かつコンソールで手動実行するよりも安全に作業を進められます。
今後も同じような状況があれば、rails runner
を活用していきたいと思います。
参考