Rails アプリケーションのテンプレート

RailsのテンプレートはシンプルなRubyファイルであり、新規または既存のRailsプロジェクトにgemやイニシャライザを追加するためのDSL(ドメイン固有言語)を含んでいます。

このガイドの内容:

  • テンプレートを使ってRailsアプリケーションの生成/カスタマイズを行う方法
  • RailsテンプレートAPIを使って再利用可能なテンプレートを開発する方法

1 利用法

テンプレートを適用するには、-mオプションを使ってテンプレートの場所を指定する必要があります。ファイルパスまたはURLのどちらでも指定可能です。

$ rails new blog -m ~/template.rb
$ rails new blog -m http://example.com/template.rb

railsコマンドapp:templateを使って、既存のRailsアプリケーションにテンプレートを適用することもできます。テンプレートの場所はLOCATION環境変数で渡す必要があります。ここでも、ファイルパスまたはURLのどちらでも指定可能です。

$ bin/rails app:template LOCATION=~/template.rb
$ bin/rails app:template LOCATION=http://example.com/template.rb

2 テンプレートAPI

RailsのテンプレートAPIはわかりやすく設計されています。以下はRailsアプリケーションの典型的なテンプレートです。

# template.rb
generate(:scaffold, "person name:string")
route "root to: 'people#index'"
rails_command("db:migrate")

after_bundle do
  git :init
  git add: "."
  git commit: %Q{ -m 'Initial commit' }
end

以下のセクションで、APIで提供される主なメソッドの概要を解説します。

2.1 gem(*args)

生成されたGemfileファイルに、指定されたgemのエントリを追加します。

たとえば、Railsアプリケーションがbjnokogiri gemに依存しているとします。

gem "bj"
gem "nokogiri"

このメソッドはGemfileにgemを追加するだけです。gemのインストールは行いません。

以下のようにバージョンを正確に指定することも可能です。

gem "nokogiri", "~> 1.16.4"

以下のようにGemfileに追加するコメントも指定できます。

gem "nokogiri", "~> 1.16.4", comment: "Add the nokogiri gem for XML parsing"

2.2 gem_group(*names, &block)

gemのエントリを指定のグループに含めます。

たとえば、rspec-rails gemをdevelopmentグループとtestグループだけで読み込みたい場合は以下のようにします。

gem_group :development, :test do
  gem "rspec-rails"
end

2.3 add_source(source, options={}, &block)

生成されたGemfileファイルに、gemの取得元を追加します。

たとえば、gemを"http://gems.github.com"から取得したい場合は以下のようにします。

add_source "http://gems.github.com"

ブロックを1つ渡すと、取得元のグループにブロック内のgemエントリがラップされます。

add_source "http://gems.github.com/" do
  gem "rspec-rails"
end

2.4 environment/application(data=nil, options={}, &block)

config/application.rbファイルのApplicationクラスの内側に指定の行を追加します。

options[:env]を指定すると、config/environmentsディレクトリに置かれている同等のファイルに追加します。

environment 'config.action_mailer.default_url_options = {host: "http://yourwebsite.example.com"}', env: "production"

data引数の代わりにブロックを1つ渡すこともできます。

2.5 vendor/lib/file/initializer(filename, data = nil, &block)

生成されたRailsアプリケーションのconfig/initializersディレクトリにイニシャライザを追加します。

たとえば、Object#not_nil?Object#not_blank?というメソッドを使いたい場合は以下のようにします。

initializer "bloatlol.rb", <<-CODE
  class Object
    def not_nil?
      !nil?
    end

    def not_blank?
      !blank?
    end
  end
CODE

同様に、lib()メソッドはlib/ディレクトリにファイルを作成し、vendor()メソッドはvendor/ディレクトリにファイルを作成します。

file()メソッドを使えば、Rails.rootからの相対パスを渡してディレクトリやファイルを自由に作成することもできます。

file "app/components/foo.rb", <<-CODE
  class Foo
  end
CODE

上のコードはapp/componentsディレクトリを作成し、その中にfoo.rbファイルを置きます。

2.6 rakefile(filename, data = nil, &block)

指定されたタスクを含むrakeファイルをlib/tasksディレクトリの下に作成します。

rakefile("bootstrap.rake") do
  <<-TASK
    namespace :boot do
      task :strap do
        puts "i like boots!"
      end
    end
  TASK
end

上のコードはlib/tasks/bootstrap.rakeファイルを作成し、その中にboot:strap rakeタスクを置きます。

2.7 generate(what, *args)

指定の引数を渡してRailsジェネレータを実行します。

generate(:scaffold, "person", "name:string", "address:text", "age:number")

2.8 run(command)

任意のコマンドを実行します(Rubyのバッククォート記法と同等です)。たとえばREADME.rdocファイルを削除する場合は以下のようにします。

run "rm README.rdoc"

2.9 rails_command(command, options = {})

指定のrailsコマンドをRailsアプリケーションで実行します。たとえばデータベースのマイグレーションを行いたい場合は次のようにします。

rails_command "db:migrate"

Railsの環境を指定してrailsコマンドを実行することもできます。

rails_command "db:migrate", env: "production"

スーパーユーザーとしてコマンドを実行することもできます。

rails_command "log:clear", sudo: true

2.10 route(routing_code)

ルーティングエントリをconfig/routes.rbファイルに追加します。上の手順では、scaffoldでpersonを生成し、続けてREADME.rdocを削除しました。今度は以下のようにしてPeopleController#indexをアプリケーションのデフォルトページにします。

route "root to: 'person#index'"

2.11 inside(dir)

指定のディレクトリでコマンドを実行します。たとえば、自分のコンピュータにedge railsリポジトリのコピーがあり、自分の新しいアプリケーションからそこにシンボリックリンクを張るには以下のようにします。

inside("vendor") do
  run "ln -s ~/commit-rails/rails rails"
end

2.12 ask(question)

ask()を使うと、ユーザー入力を受け取ってテンプレートで利用できます。たとえば、新しく追加するライブラリ名をユーザーに入力させるには以下のようにします。

lib_name = ask("ライブラリに付ける名前を入力してください")
lib_name << ".rb" unless lib_name.index(".rb")

lib lib_name, <<-CODE
  class Shiny
  end
CODE

2.13 yes?(question)またはno?(question)

テンプレートでのユーザー入力に応じて処理の流れを決めたい場合に使います。たとえば、ユーザーにマイグレーションを実行するようプロンプトを以下のように表示できます。

rails_command("db:migrate") if yes?("データベースマイグレーションを実行しますか?")
# no?(question)はyes?と逆の動作

2.14 git(:command)

Railsテンプレートで任意のgitコマンドを実行します。

git :init
git add: "."
git commit: "-a -m 'Initial commit'"

2.15 after_bundle(&block)

gemのバンドルとbinstub生成の完了後に実行したいコールバックを登録します。生成したすべてのファイルをバージョン管理に追加したい場合に便利です。

after_bundle do
  git :init
  git add: "."
  git commit: "-a -m 'Initial commit'"
end

これらのコールバックは--skip-bundleを指定した場合でもスキップされずに実行されます。

3 高度な利用法

アプリケーションテンプレートは、Rails::Generators::AppGeneratorインスタンスのコンテキストで評価されます。ここで使われるapplyアクションはThorが提供しています。 これにより、このインスタンスを必要に応じて拡張および変更できます。

たとえば、source_pathsメソッドを上書きしてテンプレートの位置を指定できます。これにより、copy_fileなどのメソッドでテンプレートの位置からの相対パスを指定できるようになります。

def source_paths
  [__dir__]
end

フィードバックについて

Railsガイドは GitHub の yasslab/railsguides.jp で管理・公開されております。本ガイドを読んで気になる文章や間違ったコードを見かけたら、気軽に Pull Request を出して頂けると嬉しいです。Pull Request の送り方については GitHub の README をご参照ください。

原著における間違いを見つけたら『Rails のドキュメントに貢献する』を参考にしながらぜひ Rails コミュニティに貢献してみてください 🛠💨✨

本ガイドの品質向上に向けて、皆さまのご協力が得られれば嬉しいです。

Railsガイド運営チーム (@RailsGuidesJP)

支援・協賛

Railsガイドは下記の協賛企業から継続的な支援を受けています。支援・協賛にご興味あれば協賛プランからお問い合わせいただけると嬉しいです。

  1. Star
  2. このエントリーをはてなブックマークに追加