rubyonrails.org에서 더 보기:

Rails Application Templates

Application template은 gem, initializer 등을 새로 생성된 Rails 프로젝트나 기존 Rails 프로젝트에 추가하기 위한 DSL이 포함된 단순한 Ruby 파일입니다.

이 가이드를 읽은 후에는 다음을 알 수 있습니다:

  • template을 사용하여 Rails 애플리케이션을 생성/커스터마이즈하는 방법
  • Rails template API를 사용하여 재사용 가능한 application template을 작성하는 방법

1 사용법

template을 적용하려면 -m 옵션을 사용하여 적용하고자 하는 template의 위치를 Rails generator에 제공해야 합니다. 이는 파일 경로나 URL이 될 수 있습니다.

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

app:template rails 명령어를 사용하여 기존 Rails 애플리케이션에 template을 적용할 수 있습니다. template의 위치는 LOCATION 환경 변수를 통해 전달해야 합니다. 마찬가지로 이는 파일 경로나 URL이 될 수 있습니다.

$ bin/rails app:template LOCATION=~/template.rb 
$ bin/rails app:template LOCATION=http://example.com/template.rb

2 Template API

Rails template API는 이해하기 쉽습니다. 다음은 일반적인 Rails template의 예시입니다:

# 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 '최초 커밋' }
end

다음 섹션에서는 API가 제공하는 주요 메서드들을 설명합니다:

2.1 gem(*args)

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

예를 들어, 애플리케이션이 bjnokogiri gem들에 의존성이 있다면:

gem "bj"
gem "nokogiri"

Gem을 추가할 때 이 메소드는 Gemfile에만 gem을 추가하며, gem을 설치하지는 않는다는 점에 유의하세요.

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

gem "nokogiri", "~> 1.16.4"

이는 nokogiri gem의 버전 1.16.4 또는 그 이후의 패치 레벨 릴리스를 사용하겠다는 의미입니다. 하지만 1.17.0과 같은 마이너 버전 변경은 하지 않습니다.

Gemfile에 추가될 주석도 추가할 수 있습니다:

gem "nokogiri", "~> 1.16.4", comment: "XML 파싱을 위한 nokogiri gem 추가"

2.2 gem_group(*names, &block)

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

예를 들어, rspec-railsdevelopmenttest 그룹에서만 로드하고 싶을 때:

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

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

생성된 애플리케이션의 Gemfile에 주어진 source를 추가합니다.

예를 들어, gem을 "http://gems.github.com"에서 가져와야 하는 경우:

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

gem 소스를 추가합니다

블록이 주어진 경우, 블록 내의 gem 항목들은 source 그룹으로 묶입니다.

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

source를 추가할 때 블록을 사용하여 해당 source에서만 사용할 gem들을 지정할 수 있습니다.

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 인자 대신 block을 사용할 수 있습니다.

2.5 vendor/lib/file/initializer(filename, data = nil, &block)

생성된 애플리케이션의 config/initializers 디렉토리에 initializer를 추가합니다.

예를 들어 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 아래에 지정된 task들을 포함하는 새로운 rake 파일을 생성합니다:

rakefile("bootstrap.rake") do
  <<-TASK
    namespace :boot do
      task :strap do
        puts "난 부츠가 좋아!"
      end
    end
  TASK
end

위 작업은 boot:strap rake 태스크를 가진 lib/tasks/bootstrap.rake 파일을 생성합니다.

2.7 generate(what, *args)

주어진 인자와 함께 지정된 rails generator를 실행합니다.

generate(:scaffold, "person", "name:string", "address:text", "age:number")

2.8 run(command)

임의의 명령어를 실행합니다. backtick과 동일하게 동작합니다. 예를 들어 README.rdoc 파일을 제거하고 싶다면 다음과 같이 합니다:

run "rm README.rdoc"

README.rdoc 파일을 삭제합니다.

2.9 rails_command(command, options = {})

Rails 애플리케이션에서 제공된 명령어를 실행합니다. 예를 들어 데이터베이스를 마이그레이션하고 싶다고 해봅시다:

rails_command "db:migrate"

다른 Rails environment로도 명령을 실행할 수 있습니다:

rails_command "db:migrate", env: "production"
```를 통해 production 환경에서 데이터베이스 마이그레이션을 실행합니다.

명령어를 super-user로 실행할 수도 있습니다:

```ruby
rails_command "log:clear", sudo: true

실패시 애플리케이션 생성이 중단되어야 하는 명령어를 실행할 수도 있습니다:

rails_command "db:migrate", abort_on_failure: true

실패시 중단(abort)하도록 설정하여 rails_command "db:migrate"를 실행합니다.

2.10 route(routing_code)

config/routes.rb 파일에 라우팅 항목을 추가합니다. 위의 단계에서 우리는 person scaffold를 생성하고 README.rdoc를 제거했습니다. 이제 PeopleController#index를 애플리케이션의 기본 페이지로 만들기 위해:

route "root to: 'person#index'"
```을 라우트 파일에 추가합니다. 이는 애플리케이션의 루트("/")를 person 컨트롤러의 index 액션으로 매핑합니다.

### inside(dir)

주어진 디렉토리에서 명령어를 실행할 수 있게 합니다. 예를 들어, 새로운 앱에서 심볼릭 링크를 걸고 싶은 edge rails의 복사본이 있다면 다음과 같이 할 수 있습니다:

```ruby
"vendor" 내부에서 다음을 실행합니다:
  run "ln -s ~/commit-rails/rails rails"
end

2.11 ask(question)

ask()는 사용자로부터 피드백을 받아 템플릿에서 활용할 수 있는 기회를 제공합니다. 예를 들어 새로 추가하는 멋진 라이브러리의 이름을 사용자가 지정하도록 하고 싶다고 가정해보겠습니다:

lib_name = ask("반짜반짜한 library의 이름을 무엇으로 하시겠습니까?") 
lib_name << ".rb" unless lib_name.index(".rb")

lib lib_name, <<-CODE
  class Shiny
  end
CODE

2.12 yes?(question) 또는 no?(question)

이 메소드들은 템플릿에서 사용자에게 질문하고 사용자의 답변에 따라 흐름을 결정할 수 있게 합니다. 예를 들어 사용자에게 migration을 실행할지 물어보고 싶다면:

yes?("데이터베이스 마이그레이션을 실행하시겠습니까?") 응답이 참이면 rails_command("db:migrate") 실행합니다.
# no?(question)는 정반대로 동작합니다.

2.13 git(:command)

Rails templates를 사용하면 어떤 git 명령어도 실행할 수 있습니다:

git :init
git add: "."
git commit: "-a -m '최초 커밋'"

2.14 after_bundle(&block)

gem들이 bundle되고 binstub들이 생성된 후에 실행될 callback을 등록합니다. 생성된 파일들을 버전 관리에 추가할 때 유용합니다:

after_bundle do
  git :init
  git add: "."
  git commit: "-a -m '최초 커밋'"
end

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

--skip-bundle 옵션이 전달되어도 콜백들은 실행됩니다.

3 고급 사용법

이것은 필요에 따라 인스턴스를 확장하고 변경할 수 있다는 것을 의미합니다.

예를 들어 source_paths 메서드를 오버라이드하여 템플릿의 위치를 포함하도록 할 수 있습니다. 이제 copy_file과 같은 메서드가 템플릿 위치에 대한 상대 경로를 허용합니다.

def source_paths
  [__dir__]
end

소스 경로를 설정합니다.



맨 위로