Rails 애플리케이션 템플릿

애플리케이션 템플릿은 젬, 초기화기 등을 새로 생성된 Rails 프로젝트나 기존 Rails 프로젝트에 추가하기 위한 DSL이 포함된 간단한 Ruby 파일입니다.

이 가이드를 읽고 나면 다음을 알 수 있습니다:

  • 템플릿을 사용하여 Rails 애플리케이션을 생성/사용자 정의하는 방법.
  • Rails 템플릿 API를 사용하여 재사용 가능한 애플리케이션 템플릿을 작성하는 방법.

사용법

템플릿을 적용하려면 -m 옵션을 사용하여 적용하려는 템플릿의 위치를 Rails 생성기에 제공해야 합니다. 이는 파일 경로 또는 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

템플릿 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에서 제공하는 주요 메서드를 설명합니다:

gem(*args)

생성된 애플리케이션의 Gemfile에 제공된 젬에 대한 gem 항목을 추가합니다.

예를 들어 애플리케이션이 bjnokogiri 젬에 의존하는 경우:

gem "bj"
gem "nokogiri"

이 메서드는 젬을 Gemfile에 추가만 하며, 젬을 설치하지는 않습니다.

정확한 버전을 지정할 수도 있습니다:

gem "nokogiri", "~> 1.16.4"

또한 Gemfile에 추가될 주석을 포함할 수 있습니다:

gem "nokogiri", "~> 1.16.4", comment: "XML 구문 분석을 위해 nokogiri 젬 추가"

gem_group(*names, &block)

젬 항목을 그룹으로 감싸줍니다.

예를 들어 rspec-railsdevelopmenttest 그룹에서만 로드하려면:

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)

config/application.rbApplication 클래스 내부에 라인을 추가합니다.

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)

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 작업을 추가합니다.

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)

지정된 디렉토리에서 명령을 실행할 수 있습니다. 예를 들어 edge rails의 복사본을 새 앱에 심볼릭 링크로 연결하려면:

inside('vendor') do
  run "ln -s ~/commit-rails/rails rails"
end

ask(question)

ask()를 사용하면 사용자의 피드백을 받아 템플릿에서 사용할 수 있습니다. 새로운 멋진 라이브러리의 이름을 사용자에게 묻고 싶다면:

lib_name = ask("새로운 멋진 라이브러리의 이름은 무엇입니까?")
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?("데이터베이스 마이그레이션을 실행하시겠습니까?")
# no?(question)은 반대로 작동합니다.

git(:command)

Rails 템플릿을 사용하면 어떤 git 명령이든 실행할 수 있습니다:

git :init
git add: "."
git commit: "-a -m 'Initial commit'"

after_bundle(&block)

젬이 번들링되고 binstub이 생성된 후 실행되는 콜백을 등록합니다. 생성된 파일을 버전 관리에 추가하는 데 유용합니다:

after_bundle do
  git :init
  git add: '.'
  git commit: "-a -m 'Initial commit'"
end

--skip-bundle이 전달된 경우에도 콜백이 실행됩니다.

고급 사용법

애플리케이션 템플릿은 Rails::Generators::AppGenerator 인스턴스의 컨텍스트에서 평가됩니다. Thor에서 제공하는 apply 액션을 사용합니다.

이는 템플릿의 요구 사항에 맞게 인스턴스를 확장하고 변경할 수 있음을 의미합니다.

예를 들어 source_paths 메서드를 재정의하여 템플릿의 위치를 포함할 수 있습니다. 그러면 copy_file과 같은 메서드가 템플릿의 상대 경로를 허용합니다.

def source_paths
  [__dir__]
end