1 利用法
アプリケーションテンプレートを適用するためには、-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
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アプリケーションがbj
とnokogiri
gemに依存しているとします。
gem "bj" gem "nokogiri"
Gemfileでgemを指定しただけではインストールされないのでご注意ください。指定したgemをインストールするためにはbundle install
を実行する必要があります。
bundle install
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
ファイルに、指定されたソースを追加します。
たとえば、"http://code.whytheluckystiff.net"
にあるgemをソースとして使いたい場合は以下のようにします。
add_source "http://code.whytheluckystiff.net"
ブロックを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
引数の代わりにブロックをひとつ渡すこともできます。
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)
任意のコマンドを実行します。いわゆるバッククォートと同等です。たとえばREADME.rdoc
ファイルを削除する場合は以下のようにします。
run "rm README.rdoc"
2.9 rails_command(command, options = {})
指定のタスクをRailsアプリケーションで実行します。たとえばデータベースのマイグレーションを行いたい場合は次のようにします。
rails_command "db:migrate"
Railsの環境を指定してrakeタスクを実行することもできます。
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をFreezeしたい場合は以下のようにします。
rails_command("rails:freeze:gems") if yes?("Freeze rails gems?") # 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
や--skip-spring
を指定した場合でもスキップされずに実行されます。
3 高度な利用法
アプリケーションテンプレートは、Rails::Generators::AppGenerator
インスタンスのコンテキストで評価されます。ここで使われるapply
アクションはThorが提供しています。
これにより、このインスタンスを必要に応じて拡張したり変更したりできます。
たとえば、source_paths
メソッドを上書きしてテンプレートの位置を指定することができます。これにより、copy_file
などのメソッドでテンプレートの位置からの相対パスを指定できるようになります。
def source_paths [__dir__] end