7 加生成器撤退
生成器的最后一个特性是对插件生成器非常有用的,就是回滚。比如,想象在TestUnit上加一个特性,像shoulda(http://github.com/thoughtbot/shoulda)一样。
因为TestUnit实现了Rails需要的所有生成器,shoulda只是想重写其中的一部分,不需全部覆盖,它就可以告诉Rails如果在Shoulda命名空间里找不到生成器,就用TestUnit生成器。
再次修改config/application.rb,我们可以简单的模仿这个行为:
config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :shoulda, :fixture => false g.stylesheets false # Add a fallback! g.fallbacks[:shoulda] = :test_unit end
现在,如果你建立了一个注释脚手架,可以看到shoulda生成器被调用,在最后,它们都退到TestUnit的生成器了。
$ rails generate scaffold Comment body:text invoke active_record create db/migrate/20091120151323_create_comments.rb create app/models/comment.rb invoke shoulda create test/unit/comment_test.rb create test/fixtures/comments.yml route map.resources :comments invoke scaffold_controller create app/controllers/comments_controller.rb invoke erb create app/views/comments create app/views/comments/index.html.erb create app/views/comments/edit.html.erb create app/views/comments/show.html.erb create app/views/comments/new.html.erb create app/views/comments/_form.html.erb create app/views/layouts/comments.html.erb invoke shoulda create test/functional/comments_controller_test.rb invoke my_helper create app/helpers/comments_helper.rb invoke shoulda create test/unit/helpers/comments_helper_test.rb
回退使你的生成器有单独的职责,越来越多的代码重用并减少代码重写。
8应用模板
现在你已经看见了生成器在应用程序里可以被调用,你知道它也可生成应用吗?这种生成器叫做“模板”。
gem("rspec-rails", :group => "test") gem("cucumber-rails", :group => "test") if yes?("Would you like to install Devise?") gem("devise") generate("devise:install") model_name = ask("What would you like the user model to be called? [user]") model_name = "user" if model_name.blank? generate("devise", model_name) end
在上面的模板中,我们指定应用程序依赖于rspec-rails和cucumber-rails的gem,这两个东西将被加到Gemfile的测试组里。然后,我们提出一个问题给用户,他们是否想安装设备,如果用户回答“Y”或“yes”,模板将在所有Gemfile组的外面添加设备,运行devise:install生成器。然后这个模板读入用户输入,运行设备生成器,用户对最后一个问题的回答被传给生成器。
modify the outcome of the rails new command by using the -m option and passing in the filename:
想象这个模板在文件template.rb里,使用rails的new命令的时候,使用-m选项,提交文件名,我们可以用它修改new的结果。
$ rails new thud -m template.rb
这个命令将生成Thud应用,执行模板,并输出。
模板不一定要存在本地系统,-m选项支持在线模板。
$ rails new thud -mhttps://gist.github.com/722911.txt
同时最后一个章节不包括生成怎样生成对人类来说最可怕的模板,它将根据你的处理,使你的方法可用,这样你就可以自己开发。这些方法对生成器也同样可用。
9生成器方法
以下对Rails生成器和模板同样适用:
注:本指南不包括Thor提供的方法,在Thor的文档里可以找到它。
9.1 plugin
plugin将安装一个插件到现有应用里。
plugin("dynamic-form", :git => "git://github.com/rails/dynamic-form.git") Available options are: ? :git – Takes the path to the git repository where this plugin can be found. ? :branch – The name of the branch of the git repository where the plugin is found. ? :submodule – Set to true for the plugin to be installed as a submodule. Defaults to false. ? :svn – Takes the path to the svn repository where this plugin can be found. ? :revision – The revision of the plugin in an SVN repository.
9.2 gem
为应用程序指定一个gem依赖。
gem("rspec", :group => "test", :version => "2.1.0") gem("devise", "1.1.5") Available options are: ? :group – The group in the Gemfile where this gem should go. ? :version – The version string of the gem you want to use. Can also be specified as the second argument to the method. ? :git – The URL to the git repository for this gem. Any additional options passed to this method are put on the end of the line: gem("devise", :git => "git://github.com/plataformatec/devise", :branch => "master") The above code will put the following line into Gemfile: gem "devise", :git => "git://github.com/plataformatec/devise", :branch => "master"
9.3 add_source
加一个特定的源到Gemfile:
add_source "http://gems.github.com"
9.4 application
在应用的类定义之后,直接加入一行到config/application.rb。
application "config.asset_host = 'http://example.com'" This method can also take a block: application do "config.asset_host = 'http://example.com'" end Available options are: ? :env – Specify an environment for this configuration option. If you wish to use this option with the block syntax the recommended syntax is as follows: application(nil, :env => "development") do "config.asset_host = 'http://localhost:3000'" end
9.5 git
运行指定的git命令:
git :init git :add => "." git :commit => "-m First commit!" git :add => "onefile.rb", :rm => "badfile.cxx" The values of the hash here being the arguments or options passed to the specific git command. As per the final example shown here, multiple git commands can be specified at a time, but the order of their running is not guaranteed to be the same as the order that they were specified in.
9.6 vendor
将一个文件放入vendor,包含特定的代码。
vendor("sekrit.rb", '#top secret stuff') This method also takes a block: vendor("seeds.rb") do "puts 'in ur app, seeding ur database'" end
9.7 lib
将一个文件放入lib,包含特定的代码。
lib("special.rb", 'p Rails.root') This method also takes a block: lib("super_special.rb") do puts "Super special!" end
9.8 rakefile
在应用的lib/tasks创建一个Rake文件。
rakefile("test.rake", 'hello there') This method also takes a block: rakefile("test.rake") do %Q{ task :rock => :environment do puts "Rockin'" end } end
9.9 initializer
在应用的config/initializers创建一个initializer文件:
initializer("begin.rb", "puts 'this is the beginning'") This method also takes a block: initializer("begin.rb") do puts "Almost done!" end
9.10 generate
运行指定的生成器,参数是生成器名,后面的参数将赋给生成器。
generate("scaffold", "forums title:string description:text")
9.11 rake
Runs the specified Rake task. rake("db:migrate") Available options are: ? :env – Specifies the environment in which to run this rake task. ? :sudo – Whether or not to run this task using sudo. Defaults to false.
9.12 capify!
在Capistrano运行capify命令,在应用程序的根目录,生成Capistrano配置。
capify!
9.13 route
给文件config/routes.rb加内容:
route("resources :people")
9.14 readme
输出参数中模板源路径的文件内容, 通常是一个README.
readme("README")
10 更改列表
December 1, 2010:加入模板和生成器的可用方法和选项文档,Ryan Bigg
December 1, 2010: 补充Rails应用模板,Ryan Bigg
August 23, 2010: 编辑通过, Xavier Noria
April 30, 2010: José Valim复核
November 20, 2009:第一稿,José Valim