Draperって何?
Draperは、Model/Controller/View/Helperと異なる第4のレイヤを提供するGemです。
この第4のレイヤは、海外では「Presenter」として分類されています。(正確にもう少し細かい分類があるらしいですが割愛♪)
このレイヤを作るメリットは、
- model/viewに余計なロジックを書かなくてすむ
- Helperのメソッドが使われている場所が不明という事態を防ぐ
日本ではPresenterレイヤでは、ActiveDecoratorというGemが有名です。ActiveDecoratorもほぼ同じことができます。
Draperの紹介
Draperの説明ならRailsCastが一番わかり易かったです(説明は日本語に翻訳されています、動画は英語です)↓
1年前の記事ですので、実際に動かしてみると少しコードの中身が違いますが、骨子は同じなのでフィーリングで動かせると思います。この記事では、showテンプレートが「1050バイト、34行」=>「382バイト、16行」になったのそうで、サイズを役2/3削減できたそうです。実際使ってみるともちろんコード量も減るんですが、それ以上に「コードのわかりやすさ」を実感できます。
ActiveDecoratorと比べたときの違いは、
- ControllerでDraper専用の宣言を追加しないといけないこと。
- helperメソッドを使うときには、「h.」か「include Draper::LazyHelpers」といった記述が必要となこと。
ちまたでの評判
ActiveDecoratorやDraperはパラダイムシフト級の超絶機能なので、Rails本体に取り込んでほしい!Railsの新たな強みになるはず。
— のりおさん (@norio) 12月 5, 2011
というほどぶっちぎりで褒められている感じです^^
Draperの導入紹介
ここからは、「Experimenting with Draper」を簡易的に訳してみたものです。
セットアップ
サンプルのGitHubプロジェクトをcloneしてセットアップ
Git clone Git://github.com/JumpstartLab/blogger_advanced.Git |
Draperのインストール
Gemfileに’draper’を追加します。
gem 'draper' |
bundle install |
Decoratorの作成
ArticleモデルのDecoratorを作成する。
rails generate decorator article |
すると
- app/decorators/フォルダが作成
- app/decorators/article_decorator.rbファイルが作成、中にはArticleDecoratorクラスがあり
- spec/decorators/フォルダが作成
- spec/decorators/article_decorator_spec.rbファイルが作成
サーバをリスタート。もし、Apacheを使っている場合は、次のコマンドを実行。
# mac |
Decoratorの使い方
articles_controllerのshowアクションを例にDecoratorを使うための変更を示します。
def show |
Decoratorを使うために、上のコードを下のように変更します。
def show |
↑か↓のどちらでもOKです。
def show |
これで、article_decorator側に記述したメソッドが使えます。
このxxxDecorator.newは単数/複数(Collection)両方に対応しています。
(例) showページにcreated_atを表示
showページにcreated_atを表示するために、Decorator側にcreated_atメソッドを追加します。
def created_at |
これで、article.created_atとするとDecorator側のメソッドが呼び出されます。
(例) Commentカウンター
show pageに以下のようなComment countメソッドがあるとします。
|
これを次のように書きなおすことでviewの見通しがよくなります。
def comments_count |
|
View側の記述がすっきりしたと思います。View側が複雑になるとviewのif/for文で読みづらくなりますが、それをDecoratorが解消してくれます。
おまけActiveDecoratorの紹介
Draperとほぼ同機能をもつ、ActiveDecoratorについても一緒に紹介します。
ActiveDecoratorはsapporo.rbでのプレゼンテーションがバズってました↓
また、上のRailsCastsのコードをactive_decoratorで書きなおした記事もあったので紹介です。
####[Rails] RailsCast #286 Draper を active_decorator で書き直してみて得たこと
実際僕も試しにActiveDecorator使った時には、ここのサイトを参考にさせていただきました。かなりわかりやすくまとまっています。
Draperと比べた時の違いは、blog.article.titleの場合に「blog」はdecorateされるが、articleはdecorateされない点だと思います。ただしこれはあくまで設計思想の違いっぽいです。
あとは余談ですが、Decorator系の使い所の難しさを指摘されている方もいます。
使いどころの難しさもあるようですが、個人的にはLet’s Try!だと思います。
🤔 補足: kaminariを使う場合
Draperとページネーターのkaminariを使う場合は、Draperがうまくkaminariのメソッドを呼び出せない場合があります。
その場合は、config/initializers/draper.rb
を作成して以下を記入しておくとエラーを回避できます。
Draper::CollectionDecorator.delegate :current_page, :total_pages, :limit_value, :total_count |
Kaminari vs Draper · Issue #401 · drapergem/draper
🚜 変更来歴
13/04/18 23:15 kaminariを使う場合の補足を追記
14/02/26 06:45リンク先のミスを修正