更多内容请访问 rubyonrails.org:

Rails 应用程序模板

应用程序模板是简单的 Ruby 文件,包含 DSL,用于将 gem、初始化器等添加到新创建的 Rails 项目或现有的 Rails 项目中。

阅读完本指南后,您将了解

  • 如何使用模板生成/自定义 Rails 应用程序。
  • 如何使用 Rails 模板 API 编写您自己的可重用应用程序模板。

1 用法

要应用模板,您需要使用 -m 选项向 Rails 生成器提供要应用的模板位置。这可以是文件路径或 URL。

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

您可以使用 app:template rails 命令将模板应用于现有的 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 条目以供提供的 gem 使用。

例如,如果您的应用程序依赖于 gem bjnokogiri

gem "bj"
gem "nokogiri"

请注意,此方法仅将 gem 添加到 Gemfile 中;它不会安装 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 条目包装在组中。

例如,如果您只想在 developmenttest 组中加载 rspec-rails

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

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

将给定的源添加到生成的应用程序的 Gemfile 中。

例如,如果您需要从 "http://gems.github.com" 获取 gem

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

如果提供了块,则块中的 gem 条目将包装在源组中。

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

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

config/application.rbApplication 类中添加一行。

如果指定了 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)

将初始化器添加到生成的应用程序的 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)

lib/tasks 下创建一个新的 rake 文件,其中包含提供的任务

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 环境运行命令

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

您还可以以超级用户的身份运行命令

rails_command "log:clear", sudo: true

您还可以运行在失败时应中止应用程序生成的命令

rails_command "db:migrate", abort_on_failure: true

2.10 route(routing_code)

将路由条目添加到 config/routes.rb 文件。在以上步骤中,我们生成了一个人员脚手架,还删除了 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("What do you want to call the shiny library ?")
lib_name << ".rb" unless lib_name.index(".rb")

lib lib_name, <<-CODE
  class Shiny
  end
CODE

2.13 yes?(question) or no?(question)

这些方法使您能够从模板中提出问题,并根据用户的回答来决定流程。假设您希望提示用户运行迁移

rails_command("db:migrate") if yes?("Run database migrations?")
# no?(question) acts just the opposite.

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 实例的上下文中评估的。它使用 Thor 提供的 apply 操作。

这意味着您可以扩展和更改实例以满足您的需求。

例如,通过覆盖 source_paths 方法以包含模板的位置。现在,像 copy_file 这样的方法将接受模板位置的相对路径。

def source_paths
  [__dir__]
end


返回顶部