Railsのテンプレートは単純なRubyファイルであり、新規または既存のRailsプロジェクトにgemやイニシャライザを追加するためのDSL (ドメイン固有言語) を含んでいます。
このガイドの内容:
gem(*args)gem_group(*names, &block)add_source(source, options={}, &block)environment/application(data=nil, options={}, &block)vendor/lib/file/initializer(filename, data = nil, &block)rakefile(filename, data = nil, &block)generate(what, *args)run(command)rails_command(command, options = {})route(routing_code)inside(dir)ask(question)yes?(question)またはno?(question)git(:command)after_bundle(&block)テンプレートを適用するためには、-mオプションを使ってテンプレートの場所を指定する必要があります。ファイルパスまたはURLのどちらでも使えます。
$ rails new blog -m ~/template.rb $ rails new blog -m http://example.com/template.rb
rakeタスクapp:templateを使って、既存のRailsアプリケーションにテンプレートを適用することもできます。テンプレートの場所はLOCATION環境変数で渡す必要があります。ここでも、ファイルパスまたはURLのどちらを使ってもかまいません。
$ bin/rails app:template LOCATION=~/template.rb $ bin/rails app:template LOCATION=http://example.com/template.rb
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で提供される主なメソッドの概要を解説します。
gem(*args)生成されたGemfileファイルに、指定されたgemのエントリを追加します。
たとえば、Railsアプリケーションがbjとnokogiri gemに依存しているとします。
gem "bj" gem "nokogiri"
Gemfileでgemを指定しただけではインストールされないのでご注意ください。指定したgemをインストールするためにはbundle installを実行する必要があります。
bundle install
gem_group(*names, &block)gemのエントリを指定のグループに含めます。
たとえば、rspec-rails gemをdevelopmentグループとtestグループだけで読み込みたい場合は以下のようにします。
gem_group :development, :test do gem "rspec-rails" end
add_source(source, options={}, &block)生成されたGemfileファイルに、指定されたソースを追加します。
たとえば、"http://code.whytheluckystiff.net"にあるgemをソースとして使いたい場合は以下のようにします。
add_source "http://code.whytheluckystiff.net"
ブロックを1つ渡すと、ブロック内のgemエントリがそのソースのグループにラップされます。
add_source "http://gems.github.com/" do gem "rspec-rails" end
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引数の代わりにブロックをひとつ渡すこともできます。
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ファイルを置きます。
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タスクを置きます。
generate(what, *args)引数を渡してRailsジェネレータを実行します。
generate(:scaffold, "person", "name:string", "address:text", "age:number")
run(command)任意のコマンドを実行します。いわゆるバッククォートと同等です。たとえばREADME.rdocファイルを削除する場合は以下のようにします。
run "rm README.rdoc"
rails_command(command, options = {})指定のタスクをRailsアプリケーションで実行します。たとえばデータベースのマイグレーションを行いたい場合は次のようにします。
rails_command "db:migrate"
Railsの環境を指定してrakeタスクを実行することもできます。
rails_command "db:migrate", env: 'production'
スーパーユーザーとしてタスクを実行することもできます。
rails_command "log:clear", sudo: true
route(routing_code)ルーティングエントリをconfig/routes.rbファイルにひとつ追加します。上の手順では、scaffoldでpersonを生成し、続けてREADME.rdocを削除しました。今度は以下のようにしてPeopleController#indexをアプリケーションのデフォルトページにします。
route "root to: 'person#index'"
inside(dir)ディレクトリを指定してコマンドをひとつ実行します。たとえば、edge railsのコピーがあり、アプリケーションからそこにシンボリックリンクを張るには以下のようにします。
inside('vendor') do run "ln -s ~/commit-rails/rails rails" end
ask(question)ask()はユーザーからのフィードバックを受け取ってテンプレートで利用するのに使います。たとえば、追加される新品のライブラリに付ける名前をユーザーに入力してもらうには、以下のようにします。
lib_name = ask("ライブラリに付ける名前を入力してください") lib_name << ".rb" unless lib_name.index(".rb") lib lib_name, <<-CODE class Shiny end CODE
yes?(question)またはno?(question)テンプレートでユーザーからの入力に基いて処理の流れを変えたい場合に使います。たとえば、指定があった場合にのみRailsをFreezeしたい場合は以下のようにします。
rails_command("rails:freeze:gems") if yes?("Freeze rails gems?") # no?(question) はyes?と逆の動作
git(:command)Railsテンプレートで任意のgitコマンドを実行します。
git :init git add: "." git commit: "-a -m 'Initial commit'"
after_bundle(&block)gemのバンドルとbinstub生成の完了後に実行したいコールバックを登録します。生成したファイルをバージョン管理するところまで自動化したい場合に便利です。
after_bundle do git :init git add: "." git commit: "-a -m 'Initial commit'" end
これらのコールバックは--skip-bundleや--skip-springを指定した場合でもスキップされずに実行されます。
テンプレートは、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ガイドは下記の協賛企業から継続的な支援を受けています。支援・協賛にご興味あれば協賛プランからお問い合わせいただけると嬉しいです。