Rails はrails new
コマンドにより、必要なファイルを即座に用意してくれます。
しかし、好みの Gem を追加したりテスト設定したり、初期設定はとても面倒な工程です...
対策としては、GitHub に生成後のテンプレートをリポジトリに残すことも一つの手段でしょう。
ただ、生成内容を調整したい時やバージョンが変わる時は、リポジトリも作り直さなければなりません。それもまた面倒ですね...
Rails は、そんな面倒なことまでも吸収してくれます。
それが**Railsジェネレータ( Rails::Generators::Base )**と呼ばれる機能です。
本記事では、例として[Rails+Vue.js]に係るCRUD入門〜Part1:環境構築編〜 - Qiitaを利用して、初期設定をコードに落とし込みます。
【目的】
rails new
によるプロジェクト生成時において、初期設定を自動化することです。
対応順は、以下の通りとなります。
なお、変更点として、初期設定の自動化はrails new
と同時に実行されるため、「プロジェクトを生成」項目が最後になります。
また、元記事から外れた内容ですが Rubocop、RSpec、Bullet も設定します。
もし、各項目の説明が不要な場合は、[1, 9, 10, 11]
の順番で読み進めてください。
- 対応順
- 事前準備
- バージョン管理の設定
-
rails generate
時の生成ファイルの設定 - foreman によるサーバの設定
- CSS フレームワークを導入
- Rubocop( 追加設定 )
- RSpec( 追加設定 )
- Bullet( 追加設定 )
- rails_template.rbの整理
- プロジェクトを生成
- 動作確認
- 最後に
- 開発環境(元記事に準じる)
- Ruby: 2.5.1
- Rails: 5.1.2
- 参考 URL
- Rails ジェネレータとテンプレート入門 - Railsガイド
- Class: Thor — Documentation for wycats/thor (master)
- hilotter/rails-application-template: rails-application-template
- dennybritz/rails_startup_template: A startup template for Ruby on Rails 4 applications
- mattbrictson/rails-template: Application template for Rails 6 projects; preloaded with best practices for TDD, security, deployment, and developer productivity.
- dao42/rails-template: A best & newest & fastest rails 6.x template for senior rails developer.
【本文】
1. 事前準備
○1: 自動化用ファイルを準備
ディレクトリ名が、プロジェクト名になるため、ご自身のプロジェクトを作成する際は、rails_vue_bookshelf
の文言を変更願います。
# プロジェクトディレクトリを生成し移動
$ mkdir rails_vue_bookshelf
$ cd rails_vue_bookshelf
# 自動化用ファイルを生成
# 今後、このファイルに自動化用コードを書き込む
$ touch rails_template.rb
○2: Node.js の準備
もし、Node.js をインストールしていない場合は、以下の記事を参考に設定願います。
ちなみに私の場合、久々に素の開発環境を使用したことから、Node.js のバージョンが古かったため、以下のエラーが発生しました。
...
rails webpacker:install
Webpacker requires Node.js ">=10.13.0" and you are using v10.4.0
Please upgrade Node.js https://nodejs.org/en/download/
Exiting!
2. バージョン管理の設定
初めに Git の設定です。
この項目は、rails new
の後に実行するコマンドでしたね。
その場合、**after_bundle(&block)**メソッドを使用します。
その名の通り、block の中身をbundle install
の後に実行します。
なお、Rails のgit(commands = {})メソッドを使用しています。
後述のrunメソッドで直接コマンドを叩く方法でも可能です。
after_bundle do
git :init
git add: "."
git commit: "-m 'First Commit'"
end
3. rails generate
時の生成ファイルの設定
次は、config/application.rb に rails generate
で生成しないファイルを設定します。
**environment(data = nil, options = {})**メソッドを使用します。
data に設定したいコードを設定すると、自動的に application.rb に挿入してくれます。
余談ですが、data は block で渡すことも可能ですし、また、options はenv: development
のように引数を指定すると、環境毎の設定も可能になります( 後述の Bullet 設定で使用)。
他にも<<-TEXT .. TEXT
は、ヒアドキュメントと呼ばれます。本記事で度々使用されるため、詳細は公式ドキュメントをご確認ください。
base_setting = <<-TEXT
config.generators do |g|
g.assets false
g.helper false
g.test_framework :rspec,
fixtures: true,
routing_specs: false,
view_specs: false,
helper_specs: false,
controller_specs: false,
request_specs: true
g.fixture_replacement :factory_bot, dir: "spec/factories" # 後述の RSpec 設定で必要となるため先に設定
end
TEXT
environment(base_setting)
4. foreman によるサーバの設定
各段階で分ける必要があるため、手順を分割します。
○1: Gemfileに追加
初めに foreman を Gemfile に追加する必要があります。
これは、通常の Gemfile と同じように記述するだけです。
gem_group :development do
gem 'foreman'
end
○2: 次のファイルを作成
runメソッドは、引数をシェルコマンドとして実行してくれます。
# Procfile.dev の設定
run "cat << TEXT > ./Procfile.dev
web: bundle exec rails s
webpacker: ./bin/webpack-dev-server
TEXT"
# bin/server の設定
run "cat << TEXT > ./bin/server
#!/bin/bash -i
bundle install
bundle exec foreman start -f Procfile.dev
TEXT"
○3: パーミッションを変更
# デフォルトでは使用不可のため、実行権限を付与
run "chmod 777 bin/server"
5. CSS フレームワークを導入
各段階で分ける必要があるため、手順を分割します。
○1: Gemfile に追加
materialize をプロジェクトに導入します。
foreman
の時と同じです。
gem 'materialize-sass'
gem 'material_icons'
○2: マニフェストファイルに設定追加
# 拡張子を css -> scss へ変更
run "mv ./app/assets/stylesheets/application.css ./app/assets/stylesheets/application.scss"
# 設定を挿入
run "cat << TEXT > ./app/assets/stylesheets/application.scss
/*
*= require_tree .
*= require_self
*= require material_icons
*/
@import 'materialize';
TEXT"
run "cat << TEXT >> ./app/assets/javascripts/application.js
//= require materialize
TEXT"
6. Rubocop( 追加設定 )
ここからは前項までの知識を使用し、初期設定を追加していきます。
本項では Rubocop を以下 URL の README を参考に設定します。
gem_group :test, :development do
gem "rubocop-airbnb", require: false
end
run "cat << TEXT > ./.rubocop_airbnb.yml
require:
- rubocop-airbnb
TEXT"
run "cat << TEXT > ./.rubocop.yml
inherit_from:
- .rubocop_airbnb.yml
AllCops:
# TargetRubyVersion:
# TargetRailsVersion:
Exclude:
- 'bin/**/*'
- 'config/**/*'
- 'db/**/*'
- 'lib/**/*'
- 'node_modules/**/*'
- 'spec/**/*'
- 'vendor/**/*'
- 'rails_template.rb'
TEXT"
7. RSpec( 追加設定 )
この項目では、以下 URL の サンプルコードを参考に RSpec を設定します。
なお、System(Feature) Spec の設定については、本記事に記載していないため、各々設定願います。
Request Spec までで十分である場合は、追加設定は必要ないかと思います。
- 参考 URL
○1: Gemfile に追加
gem_group :test, :development do
gem "rspec-rails"
gem "spring-commands-rspec"
gem "factory_bot_rails"
gem "database_rewinder"
end
○2: RSpec に必要なファイルを準備
RSpec を設定するrails generate rspec:install
コマンドは、Gem のインストール後でないと出来ません。
Git の時は、after_bundleを使用しましたが、実のところ次のようにbundle install
を先に実行できます。
run "bundle install -j4"
# Setting rspec-rails
generate "rspec:install"
run "cat << TEXT > ./.rspec
--require spec_helper
--format documentation
TEXT"
# Setting spring-commands-rspec
run "bundle exec spring binstub rspec"
# Enable ./spec/support directory
run "mkdir ./spec/support"
uncomment_lines "spec/rails_helper.rb", /Dir\[Rails\.root\.join/
# Setting factory_bot_rails
run "cat << TEXT > ./spec/support/factory_bot.rb
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
TEXT"
# Setting database_rewinder
run "cat << TEXT > ./spec/support/database_rewinder.rb
RSpec.configure do |config|
config.before(:suite) do
DatabaseRewinder.clean_all
# or
# DatabaseRewinder.clean_with :any_arg_that_would_be_actually_ignored_anyway
end
config.after(:each) do
DatabaseRewinder.clean
end
end
TEXT"
8. Bullet( 追加設定 )
○1: Gemfile に追加
gem_group :test, :development do
gem "bullet"
end
○2: Bullet に必要なファイルを準備
Bullet は、開発環境のみで必要になるライブラリです。
そのため、初期設定の情報は、config/environment/development.rb に記載します。
bullet_application_setting = <<-TEXT
config.after_initialize do
Bullet.enable = true
Bullet.alert = true
Bullet.bullet_logger = true
Bullet.console = true
Bullet.rails_logger = true
end
TEXT
environment(bullet_application_setting, env: "development")
9. rails_template.rbを整理
さて、初期設定の自動化に必要なコードが全て揃いました。
設定情報を整理しましょう。
○1: 完成した rails_template.rb
# ==========================
# Gem settings
gem 'materialize-sass'
gem 'material_icons'
gem_group :development do
gem 'foreman'
end
gem_group :test, :development do
gem "rubocop-airbnb", require: false
gem "rspec-rails"
gem "spring-commands-rspec"
gem "factory_bot_rails"
gem "database_rewinder"
gem "bullet"
gem "pry-rails" # 追加箇所1
gem "pry-byebug" # 追加箇所2
end
# ==========================
# Application settings
# --------------------------
# Base setting
base_setting = <<-TEXT
config.generators do |g|
g.assets false
g.helper false
g.test_framework :rspec,
fixtures: true,
routing_specs: false,
view_specs: false,
helper_specs: false,
controller_specs: false,
request_specs: true
g.fixture_replacement :factory_bot, dir: "spec/factories" # 後述の RSpec 設定で必要となるため先に設定
end
TEXT
environment base_setting
# --------------------------
# Bullet setting
bullet_application_setting = <<-TEXT
config.after_initialize do
Bullet.enable = true
Bullet.alert = true
Bullet.bullet_logger = true
Bullet.console = true
Bullet.rails_logger = true
end
TEXT
environment bullet_application_setting, env: "development"
# --------------------------
# foreman setting
run "cat << TEXT > ./Procfile.dev
web: bundle exec rails s
webpacker: ./bin/webpack-dev-server
TEXT"
run "cat << TEXT > ./bin/server
#!/bin/bash -i
bundle install
bundle exec foreman start -f Procfile.dev
TEXT"
run "chmod 777 bin/server"
# ==========================
# CSS framework settings
run "mv ./app/assets/stylesheets/application.css ./app/assets/stylesheets/application.scss"
run "cat << TEXT > ./app/assets/stylesheets/application.scss
/*
*= require_tree .
*= require_self
*= require material_icons
*/
@import 'materialize';
TEXT"
run "cat << TEXT >> ./app/assets/javascripts/application.js
//= require materialize
TEXT"
# ==========================
# Test settings
# --------------------------
# Rubocop
run "cat << TEXT > ./.rubocop_airbnb.yml
require:
- rubocop-airbnb
TEXT"
run "cat << TEXT > ./.rubocop.yml
inherit_from:
- .rubocop_airbnb.yml
AllCops:
# TargetRubyVersion:
# TargetRailsVersion:
Exclude:
- 'bin/**/*'
- 'config/**/*'
- 'db/**/*'
- 'lib/**/*'
- 'node_modules/**/*'
- 'spec/**/*'
- 'vendor/**/*'
- 'rails_template.rb'
TEXT"
# --------------------------
# RSpec
run "bundle install -j4"
# Setting rspec-rails
generate "rspec:install"
run "cat << TEXT > ./.rspec
--require spec_helper
--format documentation
TEXT"
# Setting spring-commands-rspec
run "bundle exec spring binstub rspec"
# Enable ./spec/support directory
run "mkdir ./spec/support"
uncomment_lines "spec/rails_helper.rb", /Dir\[Rails\.root\.join/
# Setting factory_bot_rails
run "cat << TEXT > ./spec/support/factory_bot.rb
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
TEXT"
# Setting database_rewinder
run "cat << TEXT > ./spec/support/database_rewinder.rb
RSpec.configure do |config|
config.before(:suite) do
DatabaseRewinder.clean_all
# or
# DatabaseRewinder.clean_with :any_arg_that_would_be_actually_ignored_anyway
end
config.after(:each) do
DatabaseRewinder.clean
end
end
TEXT"
after_bundle do
git :init
git add: "."
git commit: "-m 'First Commit'"
end
# 追加箇所3
if yes? "run migrate? yes/no"
rails_command "db:create"
rails_command "db:migrate"
end
○2: 追加箇所の補足
- 追加箇所1、2
- デバッグをする際に有用な Gem ですので、詳細は割愛します。
- 参考 URL: pry-byebug を使ってRailsアプリをデバックする方法 - Qiita
- 追加箇所3
- **if yes?**は
rails new
の生成途中において、Yes or No で block 内の実行可否を選択できるようになります。 -
rails_commandは、コマンドラインにおける
rails
に該当します。 - つまり、プロジェクト生成途中に
run migrate? yes/no
と選択を迫られyes
を入力すると、rails db:create
とrails db:migrate
が実行されるわけです。
- **if yes?**は
10. プロジェクトを生成
仕上げに元記事のコマンドの末尾に-m ./rails_template.rb
を渡すことで、初期設定の自動化は完了し、初期設定完了済みのプロジェクトが生成されます。
$ rails new . --webpack=vue --skip-test -m ./rails_template.rb
11. 動作確認
以下のコマンドを実行して、いつもの画面が表示されたら初期設定の自動化は成功です。
$ bin/server
$ open http://localhost:5000
# 以下のコマンドも動作確認
$ rubocop
$ rspec
12. 最後に
実は、元記事の動作確認以降の項目も自動化が可能です。
しかし、本記事は、様々な用途に使えるテンプレートを作成することが目的であったため、そこまでは追求しませんでした。
そのため、もし余力がありましたら、Rails ジェネレータとテンプレート入門 - Railsガイドを読み解きつつ、ぜひ取り組んでみてください。
あと、Gemfile も散らかってしまいますので、整理願います
【あとがき】
全くの余談ですが、Alchemy、Refinery、Spina などの OSS の初期設定時にもジェネレータが使用されています。また、記事内の rspec::install
もジェネレータです。
Rails を使用してテンプレートを生成する際には、よく使用される機能なのかもしれませんね。