概述
目前公司的新项目很多都是基于Rails开发,不同的服务都需要不同的Rails项目。而每一个Rails项目中往往会需要配置同样的Gem包,如mysql 、grape、rspec等。另一方面,可能有的Gem包并不是所有的项目都是通用的,比如redies, sidekiq、mina等。
因此,萌发了写死通用Gem包的配置 + 用脚手架配置可选Gem的想法。这篇博客,便是以Rails guides上的指南Creating and Customizing Rails Generators & Templates,学习脚手架的构造,并对其未深入的地方进行探究。如有理解错误,还请斧正。
第一个脚手架
查看现有脚手架列表
rails generate
#detail
rails generate example --help
创建脚手架
1.自建文件
#file in lib/generators/initializer_generator.rb
class InitializerGenerator < Rails::Generators::Base
def create_initializer_file
create_file "config/initializers/initializer.rb", "# Add initialization content here"
end
end
之后运行
rails generate initializer
会生成config/initializers/initializer.rb文件, 文件内容为
#Add initialization content here
有以下几个方面需要额外说明一下:
1) 函数名不影响功能,运行脚手架命令式,函数会被依次调用;
2) create_file这类函数来自于Thor, 后文会详细说明。
3) 除了继承自Rails::Generators::Base, 还可以继承自Rails::Generators::NamedBase.后文在Generators基类部分讲到。
2.用脚手架初始化创建脚手架
bin/rails generate generator initializer
create lib/generators/initializer
create lib/generators/initializer/initializer_generator.rb
create lib/generators/initializer/USAGE
create lib/generators/initializer/templates
其中,
#lib/generators/initializer/initializer_generator.rb
class InitializerGenerator < Rails::Generators::NamedBase
source_root File.expand_path("../templates", __FILE__)
end
其中initializer_generator.rb和USAGE为文件,templates为文件夹
source_root方法指示, 脚手架的templates文件的目录位置。默认为”../templates/目录下”。
其中,templates文件中一般是存放文件,在generator文件函数中,通过Thor template的函数进行文件的创建。template的第一个参数是文件名,用erb对文件进行解析。
rspec使用脚手架的实例
rails generate rspec:helper test
create spec/helpers/test_helper_spec.rb
内容为
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the TestHelper. For example:
#
# describe TestHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe TestHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end
当运行如下脚手架时:
rails generate initializer
rails会按照如下顺序寻找运行代码:
lib/rails/generators/initializer/initializer_generator.rb
lib/generators/initializer/initializer_generator.rb
lib/rails/generators/initializer_generator.rb
lib/generators/initializer_generator.rb
如果以上目录都没有找到,则报错。
所以,可以发现,若采用第一种方式建立的脚手架,优先级会低于第二种方式建立脚手架的。并且,推荐使用第二种方式的文件组织形式。
Generators基类::
- Rails::Generators::Base:
rails generate test [options]
- Rails::Generators::NamedBase: 期待传入一个NAME参数,当需要创建一个自定义名字的文件时,这种方式很有效。
rails generate test NAME [options]
#generator文件中
def create_test_generator
copy_file "initializer.rb", "config/initializers/#{file_name}.rb"
end
参考资料
Creating and Customizing Rails Generators & Templates
Thor’s Documents