2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rails8系のscriptフォルダの紹介とデータ移行のためにscriptをブラウザから実行したくてGemを作った話

Last updated at Posted at 2024-12-19

はじめに

本番環境にsshしてrails cを使ってデータを弄るとかはしたくないですよね。
まさか、まさか、そんなこと誰もしていないと思います...。

...と言いつつ、まだ環境が整い切ってない現場では、稀によくある話だとも思っています。

実際僕もたまにやってしまっていたので、それを解決する手段ないかと検討していました。

今回はそんな課題に対して、「こんな手法の解決策ができるかな」ってことを試したくて、Gemを作ってみました。(ちなみに、Gemはほぼ作ったことないGem初心者です。)

また、このGemはrails8系から入ったscriptフォルダも関連しています。

この記事では、

  • データ移行の課題と
  • (あまり有名でないと思うので)scriptフォルダの説明と
  • 作ったGemの話

をしていきます。
が、まずはどんなもの作ったか紹介した方がわかりやすいので、作ったものの紹介です。

作ったGem - Scriptor

scriptor2.gif

これは何ができるのかというと、

  • ブラウザからscriptフォルダのコードが閲覧できて
  • ブラウザからscriptフォルダのコードが実行できて
  • ブラウザからscriptフォルダのコードの実行履歴が見られる

みたいなことができます。リポジトリはこちらです。

ってことで、続いてこのGemを作った背景を書いてきます。

データ移行どうやってる?

データ移行の方法は、よく話題になるトピックと思います。

これまでのデータを修正するやり方は、maintenance_tasks gemを使ったり、data_migrate gemを使ったり、はたまた rake task を実行することだと思います。

maintenance_tasks gem は私も普段お仕事でお世話になっています。

Rails Guide には

データをマイグレーションで操作するよりも、maintenance_tasks gemの利用を検討してください。このgemは、スキーマのマイグレーションを妨げることなく、安全かつ簡単に管理できる方法で

と、maintenance_tasks gemの利用が勧められていますね。

一方で、maintenance_task を導入するほどではないような場合、rake taskを書いて実行することもメジャーな手法と思います。

maintenance_taskが出てくる以前は、rake taskでの実行が非常に多かった印象です。

そんないろいろな手段があるなか、(全く紹介されているのを見かけないので有名ではない気がしますが) Ruby on Rails 8.0.0からは、 scriptフォルダというのが誕生しました。

このプルリクエストで作られています。

scriptフォルダについて

Rails Guideには、scriptフォルダについて

使い捨て、または汎用のスクリプトやベンチマークをここに置きます。

と説明されています。scriptフォルダの使い方が書かれているscript/USAGEにも

Generate a one-off or general purpose script, such as a data migration script, cleanup script, etc.

つまり「単発のデータ移行のためのscriptを生成する」と書いていそうです。

ってことで、実はひっそりと、Rails8系から、単発のデータ移行のためにscriptフォルダってものが提供されるようになりました。

scriptフォルダの使い方

このscriptフォルダの使い方は非常に簡単です。

bin/rails generate script my_script

と実行すると script/my_script.rb ファイルが生成されます。

そしてscript/my_script.rbファイルはデフォルトでは、以下のようになっています。

require_relative "../config/environment"

# Your code goes here

非常に簡単ですね。このファイルをいじってRailsのコードを書いていきます。

例えば、以下のように書いてデータの移行を行なったりができます。

require_relative "../../config/environment"

title, body = ARGV

if post = Post.find_by(title: title)
  post.update!(body: body)
  puts "Post updated!"
else
  Post.create!(title: title, body: body)
  puts "Post created!"
end

このscriptフォルダの実行方法は、例えば以下です。

ruby script/my_script.rb hello world

ってことで簡易的なものを実行するのにはscriptフォルダも良さそうです。

もっとscriptフォルダの背景について知りたい場合は Is there any “official” way to organize one-off scripts? が参考になるかもしれません。

このスクリプトをブラウザから実行させたいし実行履歴を管理したい

このscriptフォルダ、簡易的データ移行については、そこそこ便利だなって思ったのですが...。
この実行のために本番環境にsshするのとかは、したくないです。
そしてこの実行のログも念の為とっておきたい、とかの欲も出てきました。

その欲を実現しようと思って作ったのが今回のScriptorというGemです。

再掲
scriptor2.gif

Scriptorの簡単な説明

このGemは

  • ブラウザからscriptフォルダのコードが閲覧できて
  • ブラウザからscriptフォルダのコードが実行できて
  • ブラウザからscriptフォルダのコードの実行履歴が見られる

ようなものです。

例えば、scriptフォルダが以下のようになっているとします。

❯ tree script                                       
script
├── migration
│   ├── hoges.rb
│   └── posts.rb
└── my_script.rb

2 directories, 3 files

このとき、http://localhost:3000/scriptor にアクセスすると以下のようなscript一覧画面が表示されます。

スクリーンショット 2024-12-20 2.05.09.png

scriptの詳細ページへ行くと、そのスクリプトのコードが載っています。

FireShot Capture 068 - Scriptor - localhost.png

このページには 🛠️Run Script ボタンがあり、そのボタンを押すと、このページのコードが実行できます。
また Scriptの実行に引数が必要ならば、textfieldに引数を書くとそれを反映してくれます。

スクリーンショット 2024-12-20 2.36.33.png

一番下には、実行の履歴も載っています。
スクリーンショット 2024-12-20 2.36.38.png

実行履歴では

  • ステータス(running, success, error)
  • 開始日時
  • 終了日時
  • 実行コマンド
  • 実行したファイル

などを保持しています。

導入

導入も簡単と思います。

  1. bundle add scriptor で scriptor gemを追加
  2. bin/rails generate scriptor:install を実行
    • config/routes.rbmount Scriptor::Engine => "/scriptor" が記載されます
    • db/migrations/****_create_scriptor_executions.scriptor.rb ファイルが作成されます
  3. scriptフォルダにスクリプトを作ると、http://localhost:3000/scriptor ページにスクリプト一覧が並びます

なかなか簡単で便利?なGemができた気がしています。

終わりに

データ移行の方法の一つとして、Rails8系からscriptフォルダが出ました。
これをうまく使えないかなと思って、今回Rails EngineのGemを作ったりしてみました。
Gem作りは慣れていないですが、楽しくやってたらちょっと良いGemできたなって気分でいます。
が、まだまだ足りていないこととか沢山ある(英語の説明もないし、テストも全然書けていない)ので、Contributeなんかも大歓迎です。Starも嬉しいです。

ってことでscriptフォルダの話と作ったGemの話は終わります。ありがとうございました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?