app/reports/templates.rb Ruport::Formatter::Template.create(:default) do |format| format.text = { :font_size => 16, :justification => :center } end이 코드를 동작하게 만들려면 명시적으로 environment.rb에 require를 추가해야 할 필요가 있는데, 클래스 탐색(class lookup)을 이용하여 자동으로 파일을 로딩할 수 없을 것이기 때문이다.
require "app/reports/templates"일단 require가 설정되면 기반 코드는 변경할 필요 없이 다음과 같은 PDF를 다시 만들어낼 수 있다:
# 템플릿 내부 Ruport::Formatter::Template.create(:book_list) do |format| # ... end # 출력결과를 렌더링할 때 BookReport.render_pdf(:template => :book_list)다른 템플릿으로부터 템플릿을 파생할 수도 있다:
Ruport::Formatter::Template.create(:small_centered, :base => :default) do |format| format.text.merge!(:font_size => 10) end마지막으로 템플릿을 이용하여 작업할 때 컨트롤러에서 모든 템플릿을 무시하게 만들려면 그렇게 할 수도 있다:
BookReport.render_pdf(:template => false)Ruport의 형식자는 광범위한 템플릿 옵션을 지원하는데, 템플릿 옵션은 API 문서에서 찾아볼 수 있다.
class BooksController < ApplicationController def index @book_report = BookReport.render_html end end이렇게 한 후 이에 대응하는 뷰는 다음과 같이 단순해 질 수 있다:
<%= @book_report %>Bibliophile의 유일한 뷰는 약간 복잡해 보일 뿐인데, 대부분 형식을 지정한 것 때문이다. 동일한 기본 보고서를 가운데로 정렬해서 볼 수도 있을 것이다:
class BooksController < ApplicationController def printable_list pdf = BookReport.render_pdf send_data pdf, :type => "application/pdf", :filename => "books.pdf" end end여러분은 우리가 HTML 보고서에서 했던 것과 같은 방법으로 PDF 보고서를 렌더링하고 있다는 사실을 알 수 있을 것이다. 그렇지만 이번에는 결과를 변수에 저장한 다음 그 결과를 send_data 메서드의 데이터로 제공하고 있다. 그리고 콘텐트 타입(content type)과 파일명(filename)도 지정하고 있다. 그 밖에 이 메서드에 대한 링크를 추가하여 보고서의 PDF 버전을 생성할 수 있도록 만들 필요가 있을 것이다.
class BooksController < ApplicationController def csv_list csv = BookReport.render_csv send_data csv, :type => "text/csv", :filename => "books.csv" end end보고서 생성을 레일즈 컨트롤러에 통합하는 것은 다른 여러 경우와 마찬가지로 간단하므로 여러분이 해야 할 일은 그뿐일 것이다.
class BookReport < Ruport::Controller stage :list def setup conditions = ["authors.id = ?", options.author] unless options.author.blank? self.data = Book.report_table(:all, :include => { :author => { :only => ["name"] } }, :only => ["name", "author.name", "pages"], :order => "books.name", :conditions => conditions) data.rename_columns("name" => "Title", "author.name" => "Author") end formatter :html do build :list do output << textile("h3. Book List") output << data.to_html end end formatter :pdf do build :list do pad(10) { add_text "Book List" } draw_table data end end formatter :csv do build :list do output << data.to_csv end end endRuport에 가해진 변경사항을 살펴보면 여러분은 바뀐 부분이 매우 적다는 것을 알 수 있을 것이다. 형식자의 경우에는 BookReport 컨트롤러에서 제공된 데이터를 모두 사용하기 때문에 바뀐 점이 없다. 새로운 코드는 setup()에만 들어 있는데, 이 코드는 단순히 기반이 되는 ActiveRecord#find 호출로 다시 전달될 몇 가지 조건을 만들 뿐이다. 아마도 유일하게 놀랄만한 사실은 보고서가 이제는 options.author 속성을 참조하고 있다는 것뿐일 것이다. script/console은 아래의 코드가 수행하는 바를 밝혀줄 것이다:
>> Author.find(1).name => "Umberto Eco" >> puts BookReport.render_csv(:author => 1) Title,Author,pages Baudolino,Umberto Eco,521위 예제에서도 볼 수 있듯이 Ruport는 렌더링시에 전달된 옵션을 취해 그 옵션을 options 객체에 할당한다. 이 규칙에서 유일하게 제외되는 것은 특별한 키워드, 가령 :file, :data, :template와 같은 것들이다.
class BooksController < ApplicationController def index session[:author] = params[:author] @book_report = render_book_list_as :html @authors = Author.find(:all) end def printable_list pdf = render_book_list_as :pdf send_data pdf, :type => "application/pdf", :filename => "books.pdf" end def csv_list csv = render_book_list_as :csv send_data csv, :type => "text/csv", :filename => "books.csv" end protected def render_book_list_as(format) BookReport.render(format, :author => session[:author]) end end여러분도 알겠지만 여기서 바뀐 부분은 특별할 게 없다. HTML 보고서를 보여주는 메인 인덱스 페이지는 드롭다운 메뉴에서 선택된 저자를 세션에 저장한다. 그런 다음 이 값은 HTML이나 CSV, PDF 형식이 렌더링될 때 전달된다. 우리는 불필요한 중복을 피하기 위한 간단한 도우미 메서드를 만들어 두었으며, 코드의 나머지 부분은 이전과 같다.
최신 콘텐츠