Skip to content

Instantly share code, notes, and snippets.

@hidakatsuya
Last active August 29, 2015 14:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hidakatsuya/b56d0a23750d330e7751 to your computer and use it in GitHub Desktop.
Save hidakatsuya/b56d0a23750d330e7751 to your computer and use it in GitHub Desktop.
Thinreports の新しい API を考える

クラスベースの実装

Generator API が使いにくい問題の解決策として、クラスベースの実装方法を考える。 なお、クラスベースでの利用は Generator の当初の設計思想に含まれているが、現状ではいろいろ足りていない。

注意: 下記コードは、実装の提案のためのものであり、実際に動作するものではない。

Report 定義

# item_report.rb

class ItemReport < Thinreports::Report::Base
  use 'item.tlf', default: true

  # 考え中
end

リストフッター/ページフッターの API 改善

v0.7.7 or lower: 現在

report = Thinreports::Reports.new layout: 'foo'

report.layout.config.list do |list|
  list.use_stores :price

  list.events.on :page_footer_insert do |e|
    e.section.item(:price).value(e.store.price)
  end

  list.events.on :footer_insert do |e|
    e.section.item(:price).value(e.store.price)
  end
end

@items.each do |item|
  report.list do |list|
    list.add_row price: item.price, name: item.name
    list.store.price += item.price
  end
end

report.generate filename: 'items.pdf'

v0.8: リストのイベントモデルを非推奨へ

  • リストのイベントモデルは非推奨へ (warn 'DEPRECATION')
  • List#overflow?List#on_page_break コールバックを使ったマニュアル作成を推奨へ

マニュアル作成のサンプルコード

report = Thinreports::Reports.new layout: 'foo'
report.list do |list|
  price = 0
  total_price = 0

  list.on_page_break do
    list.page_footer price: price
    total_price += price
    price = 0
  end

  @items.each do |item|
    list.add_row price: item.price, name: item.name
    price += item.price
  end

  list.on_page_break.call
  list.footer price: total_price
end

report.generate filename: 'items.pdf'

ローカル変数を使うことが微妙なら, こんな風にもできると良いかも。

report.list do |list|
  list.page_footer.item(:price).value = 0
  list.footer.item(:price).value = 0

  list.on_page_break do
    list.footer.item(:price).value += list.page_footer.item(:price).value
    list.page_footer.item(:price).value = 0
  end

  @items.each do |item|
    list.add_row price: item.price, name: item.name
    list.page_footer.item(:price).value += item.price
  end

  list.on_page_break.call
  # すでに list.footer.item(:price) は合計値が入っているので下記は不要
  # list.footer price: total_price
end

うーん、ちょっと冗長すぎる。微妙..。根本的な解決策にはならないが list.footer[:price].value とかできれば少しはマシか。

v1.0?: リストイベントは廃止、Editor で集計/件数/平均を設定可能へ

  • リストのイベントモデルを廃止へ (List#events #=> NoMethodError)
  • Editor 上でページフッター/フッターのテキストボックスに対して、自動集計の設定オプションを追加

自動集計の設定オプション

  • 例えば、商品の合計金額をフッター/ページフッターの :price テキストブロックに表示させるとき、 :price テキストブロックのプロパティで "集計する: Yes" みたいな設定をしておくと、何もしなくても勝手に集計値がセットされる機能
  • 明示的に集計ソースとなる繰り返し行のテキストブロック ID を指定することも可能

問題点

Generator API が使いにくい

  • リストのフッター/ページフッターの API がコールバックみたいになっててよくわからない
  • リストのヘッダーを操作する API がとっても中途半端

そもそもの問題点(アーキテクチャレベル)

  • レイアウトの「ページ」という概念がいろいろ難しくしている(API の仕様にもよるが)
  • テキストボックスは expand するのに、リスト/ページが expand しない
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment