Ruby on Rails の Command Line は豊富で、開発や運用に必要なタスクが揃っています。
カスタム Rake タスクも便利で、開発や運用に必要なタスクを追加することができます。
カスタム Rake タスクの数が増えると継続的な開発が困難になるので、規約を検討しました。
Rails Tasks CoC
主に検討した規約(CoC)は3つ
- Rake タスクの ネームスペース で、単一機能ごとに
.rake
ファイルを分離する。 - Rake タスクの
.rake
ファイルには、単一機能ごとのクラスの.call
を記述する。 - Rake タスクの DB の操作は dry run で試行ができ、 trail で結果を確認できる。
Hands-on
- Rails 8 で追加され認証ジェネレータの Hands-on で Rails Tasks の CoC を紹介します。
Rails new
-
rails new
コマンドで Rails に必要なファイルが作成されます。 - Rails Tasks はデフォルトでも 60 件以上 あります。
- 昔のRailsは
rake --tasks
コマンドでしたが、今はrails --tasks
も使えます。
- 昔のRailsは
$ rails new myapp && cd myapp
$ rails --tasks | wc -l # 61
Rails Generate Authentication
-
rails generate authentication
コマンドでcurrent
,user
,session
のモデルやコントローラーなど必要なファイルが作成されます。 -
rails db:migrate
コマンドでデータベースにusers
,sessions
のテーブルが作成されます。
$ rails generate authentication
$ rails db:migrate
Custom Rails Tasks
- データベースの users のテーブルのレコードの作成に Custom Rake(Rails) Tasks を利用します。
-
rails generate task users create
コマンドでlib/tasks/users.rake
ファイルが作成されます。-
rails generate task
コマンドの第一引数はnamespace
で、 第二引数はtask
です。
-
$ rails generate task users create
-
rails --tasks
コマンドを実行すると、bin/rails users:create
が追加されています。
lib/tasks/users.rake
namespace :users do
desc "TODO"
task create: :environment do
end
end
Namespace
- Rake タスクを単一機能ごとに分離するために
namespace
を利用します。 -
mkdir
コマンド とmv
コマンドで単一機能の.rake
ファイルを配置します。
mkdir lib/tasks/users
mv lib/tasks/users.rake lib/tasks/users/create.rake
-
tasks/users/create
の順番になるようにtasks
のnamespace
上位階層に追加します。 -
rails --tasks
コマンドを実行すると、bin/rails tasks:users:create
が追加されています。
lib/tasks/users/create.rake
namespace :tasks do
namespace :users do
desc "create users"
task create: :environment do
end
end
end
Call
- ユーザーを作成する
Users::CreateTask
クラスの.call
を記述します。 - ログの出力は
Rails.logger
を利用します。 -
rails --tasks
コマンドを実行すると、bin/rails tasks:users:create[password]
が追加されています。
lib/tasks/users/create.rake
# bin/rails tasks:users:create[123]
namespace :tasks do
namespace :users do
desc "create users"
task :create, %i[password] => :environment do |_task, args|
Rails.logger = Logger.new($stdout)
Rails.logger.info Users::CreateTask.call(password: args.password)
end
end
end
Application Tasks
- 単一機能ごとのクラスは
app/tasks
にファイルを配置します。 -
ApplicationTask
クラスでcall
メソッド のみを利用するようにprivate_class_method
で制御します。
$ mkdir app/tasks
$ touch app/tasks/application_task.rb
- attr_accessor で
dry_run
,trail
をインスタンス変数で読み書きできるようにします。
app/tasks/application_task.rb
class ApplicationTask
private_class_method :new
def self.call(*params)
new(*params).send(:call)
end
attr_accessor :dry_run, :trail
def initialize(params)
@dry_run = ENV['DRY_RUN'].present?
@trail = { dry_run:, params:, message: {} }
end
end
Users Create Task
- ユーザーを作成する
Users::CreateTask
クラスはapp/tasks/users
にファイルを配置します。
mkdir app/tasks/users
touch app/tasks/users/create_task.rb
app/tasks/users/create_task.rb
class Users::CreateTask < ApplicationTask
def initialize(params)
@password = params[:password]
super
end
def call
ActiveRecord::Base.transaction do
user = User.create_with(password: @password).find_or_create_by!(email_address: "dev+#{User.count + 1}@example.com")
trail[:message][:user] = { email_address: user.email_address }
raise ActiveRecord::Rollback if dry_run
end
trail
end
end
Users Create Tests
- テストは
test
やspec
にファイルを配置します。test/tasks/users/create_task_test.rb
spec/tasks/users/create_task_spec.rb
(今回は割愛します。)
Rails Tasks Run
-
bin/rails tasks:users:create[123]
コマンドで、ユーザーが作成されます。
$ bin/rails tasks:users:create[123]
dry run
-
dry run
は引数やネームスペースで対応を検討しましたが、環境変数の利用がDRYに記述できるので採用しました。
$ DRY_RUN=true bin/rails tasks:users:create[123]
Rails Authentication
-
rails generate controller Home index
コマンドで Signed を確認するWelcome
ページに必要なファイルが作成されます。
$ rails generate controller Home index
Views
-
Turbo を利用しているので
turbo_method: :delete
を設定します。
app/views/home/index.html.erb
<h1>Welcome</h1>
<p>Signed in as: <%= Current.user.email_address %></p>
<%= link_to 'Sign out', session_path, data: { turbo_method: :delete } %>
Routes
-
root
にhome#index
を設定します。
config/routes.rb
Rails.application.routes.draw do
resource :session
resources :passwords, param: :token
root "home#index"
end
Rails Server Run
-
rails server
コマンドで起動して http://localhost:3000/ にアクセスします。 - UnSigned の場合は http://localhost:3000/session/new にリダイレクトされます。
$ rails server
Sign in
- Rails Tasks で作成した メールアドレス と パスワード を入力します。
Signed in
- メールアドレス と パスワード が一致すると Welcome ページが表示されます。
まとめ
カスタム Rake タスク も CoC や DRY で 継続的な開発が保てるようにしましょう。
認証ジェネレータは Hands-on をするときに、必要なファイルが作成されるので便利です。
ポート株式会社 サービス開発部 Advent Calendar 2024 の10日目と並走しています。