3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails ジェネレータを使って初期設定を自動化しよう!

Last updated at Posted at 2020-05-03

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]の順番で読み進めてください。

  • 対応順
    1. 事前準備
    2. バージョン管理の設定
    3. rails generate時の生成ファイルの設定
    4. foreman によるサーバの設定
    5. CSS フレームワークを導入
    6. Rubocop( 追加設定 )
    7. RSpec( 追加設定 )
    8. Bullet( 追加設定 )
    9. rails_template.rbの整理
    10. プロジェクトを生成
    11. 動作確認
    12. 最後に


【本文】

1. 事前準備

○1: 自動化用ファイルを準備

ディレクトリ名が、プロジェクト名になるため、ご自身のプロジェクトを作成する際は、rails_vue_bookshelfの文言を変更願います。

bash
# プロジェクトディレクトリを生成し移動
$ mkdir rails_vue_bookshelf
$ cd rails_vue_bookshelf

# 自動化用ファイルを生成
# 今後、このファイルに自動化用コードを書き込む
$ touch rails_template.rb

○2: Node.js の準備

もし、Node.js をインストールしていない場合は、以下の記事を参考に設定願います。

ちなみに私の場合、久々に素の開発環境を使用したことから、Node.js のバージョンが古かったため、以下のエラーが発生しました。

bash
...
       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
メソッドで直接コマンドを叩く方法でも可能です。

rails_template.rb
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は、ヒアドキュメントと呼ばれます。本記事で度々使用されるため、詳細は公式ドキュメントをご確認ください。

rails_template.rb
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 と同じように記述するだけです。

rails_template.rb
gem_group :development do
  gem 'foreman'
end

○2: 次のファイルを作成

runメソッドは、引数をシェルコマンドとして実行してくれます。

rails_template.rb
# Procfile.dev の設定
run "cat << TEXT > ./Procfile.dev
web: bundle exec rails s
webpacker: ./bin/webpack-dev-server
TEXT"
rails_template.rb
# bin/server の設定
run "cat << TEXT > ./bin/server
#!/bin/bash -i
bundle install
bundle exec foreman start -f Procfile.dev
TEXT"

○3: パーミッションを変更

rails_template.rb
# デフォルトでは使用不可のため、実行権限を付与
run "chmod 777 bin/server"

5. CSS フレームワークを導入

各段階で分ける必要があるため、手順を分割します。

○1: Gemfile に追加

materialize をプロジェクトに導入します。
foremanの時と同じです。

rails_template.rb
gem 'materialize-sass'
gem 'material_icons'

○2: マニフェストファイルに設定追加

rails_template.rb
# 拡張子を 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 を参考に設定します。

rails_template.rb
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 までで十分である場合は、追加設定は必要ないかと思います。

○1: Gemfile に追加

rails_template.rb
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を先に実行できます。

rails_template.rb
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 に追加

rails_template.rb
gem_group :test, :development do
  gem "bullet"
end

○2: Bullet に必要なファイルを準備

Bullet は、開発環境のみで必要になるライブラリです。
そのため、初期設定の情報は、config/environment/development.rb に記載します。

rails_template.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

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
  • 追加箇所3
    • **if yes?**はrails newの生成途中において、Yes or No で block 内の実行可否を選択できるようになります。
    • rails_commandは、コマンドラインにおけるrailsに該当します。
    • つまり、プロジェクト生成途中にrun migrate? yes/noと選択を迫られyesを入力すると、rails db:createrails db:migrateが実行されるわけです。

10. プロジェクトを生成

仕上げに元記事のコマンドの末尾に-m ./rails_template.rbを渡すことで、初期設定の自動化は完了し、初期設定完了済みのプロジェクトが生成されます。

bash
$ rails new . --webpack=vue  --skip-test -m ./rails_template.rb

11. 動作確認

以下のコマンドを実行して、いつもの画面が表示されたら初期設定の自動化は成功です。

bash
$ bin/server
$ open http://localhost:5000

# 以下のコマンドも動作確認
$ rubocop
$ rspec

12. 最後に

実は、元記事の動作確認以降の項目も自動化が可能です。
しかし、本記事は、様々な用途に使えるテンプレートを作成することが目的であったため、そこまでは追求しませんでした。

そのため、もし余力がありましたら、Rails ジェネレータとテンプレート入門 - Railsガイドを読み解きつつ、ぜひ取り組んでみてください。

あと、Gemfile も散らかってしまいますので、整理願います :pray:

【あとがき】

全くの余談ですが、Alchemy、Refinery、Spina などの OSS の初期設定時にもジェネレータが使用されています。また、記事内の rspec::installもジェネレータです。

Rails を使用してテンプレートを生成する際には、よく使用される機能なのかもしれませんね。

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?