Шаблоны приложений - это простые Ruby файлы, содержащие DSL для добавления гемов, инициализаторов и т.п. в ваш только что созданный или существующий Rails проект.
После прочтения данного руководства, вы узнаете:
Чтобы применить шаблон, вам необходимо запустить генератор Rails с расположением шаблона, который вы хотите применить, используя опцию -m
. Это может быть путь к файлу или URL.
$ rails new blog -m ~/template.rb
$ rails new blog -m http://example.com/template.rb
Вы можете использовать команду rails 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)
Добавляет запись gem
для предоставляемого гема в генерируемый для приложения Gemfile
.
Например, если ваше приложение зависит от гемов bj
и nokogiri
:
gem "bj"
gem "nokogiri"
Пожалуйста, отметьте, что это не установит гемы и вы должны будете запустить bundle install
для этого.
$ bundle install
gem_group(*names, &block)
Оборачивает записи гемов внутрь группы.
Например, если вы хотите загружать rspec-rails
только в группах development
и test
:
gem_group :development, :test do
gem "rspec-rails"
end
add_source(source, options={}, &block)
Добавляет переданный источник в генерируемый для приложения Gemfile
.
Например, если вам необходим источник гема "http://gems.github.com"
:
add_source "http://gems.github.com"
Если передан блок, то записи гемов в блоке будут обернуты в группу с источником.
add_source "http://gems.github.com/" do
gem "rspec-rails"
end
environment/application(data=nil, options={}, &block)
Добавляет строчку внутрь класса Application
в config/application.rb
.
Если указана 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)
Добавляет инициализатор в папку 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
с rake задачей boot:strap
.
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 окружениями:
rails_command "db:migrate", env: 'production'
Вы также можете запустить команды как супер-пользователь:
rails_command "log:clear", sudo: true
Также можно запустить команды, которые должны прервать генерацию приложения в случае неудачи:
rails_command "db:migrate", abort_on_failure: true
route(routing_code)
Добавляет запись маршрутизации в файл config/routes.rb
. В шагах выше мы сгенерировали скаффолд для person и также удалили README.rdoc
. Сейчас, сделаем для приложения PeopleController#index
страницей по умолчанию:
route "root to: 'person#index'"
inside(dir)
Позволяет вам запускать команды из данного каталога. Например, если у вас есть копия крайних rails, и вы хотите сделать ссылку из вашего нового приложения, вы можете сделать:
inside('vendor') do
run "ln -s ~/commit-rails/rails rails"
end
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
yes?(question) or no?(question)
Эти методы позволяют вам задать вопросы из ваших шаблонов и принять решение в процессе в зависимости от ответа пользователя. Допустим, вы хотите спросить пользователя, запускать ли миграции:
rails_command("db:migrate") if yes?("Run database migrations?")
# no?(question) работает наоборот.
git(:command)
Шаблоны Rails позволяют вам запускать любую команду git:
git :init
git add: "."
git commit: "-a -m 'Initial commit'"
after_bundle(&block)
Регистрирует колбэк, который будет выполняться после того, как гемы были упакованы и бинстабы сгенерированы. Полезно для добавления генерируемых файлов в систему контроля версий:
after_bundle do
git :init
git add: '.'
git commit: "-a -m 'Initial commit'"
end
Колбэки выполняется, даже если был передан --skip-bundle
.
Шаблон приложения вычисляется в контексте экземпляра Rails::Generators::AppGenerator
. Используется экшн apply
, предоставленный Thor.
Это означает, что вы можете расширить и изменить экземпляр в соответствии с вашими потребностями.
Например, переписать метод source_paths
, чтобы он содержал место расположения шаблона. Сейчас методы, такие как copy_file
, будут принимать относительные пути по отношению к месту расположения шаблону.
def source_paths
[__dir__]
end