3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Draper::CollectionDecoratorにwithとかcontextとか渡せる

Posted at

いきなり詳しくはこちら

withについて

通常のDecoratorではなく、別のDecoratorを使いたい時に指定する。
例えば、ユーザは個々の詳細画面(プロフィール画面とか)持ってて、管理者側からは別の詳細画面を作る場合。

class UserDecroator < ApplicationDecorator
  delegate_all

  def show_link(options = nil) 
    options ||= {}
    h.link_to(name, user_path(object), options)
  end
end
class Admin::UserDecorator < ApplicationDecorator
  delegate_all

  def show_link(options = nil)
    options ||= {}
    h.link_to(name, admin_user_path(object), options)
  end
end

@users.decorate.each do |user|
  user.show_link
  # => <a href="/users/1">ほげ</a>
end

@users.decorate(with: Admin::UserDecorator).each do |user|
  user.show_link
  # => <a href="/admin/users/1">ほげ</a>  
end

contextについて

追加でデータを渡したい場合に使うらしい。
こんなユースケースあるか知らんがこんな感じ。

class UserDecroator < ApplicationDecorator
  delegate_all

  def show_link(options = {}) 
    options.merge(context[:show_link_options] || {})
    h.link_to(name, user_path(object), options)
  end
end
class Admin::UserDecorator < ApplicationDecorator
  delegate_all

  def show_link(options = {})
    options.merge(context[:show_link_options] || {})
    h.link_to(name, admin_user_path(object), options)
  end
end

@users.decorate(context: { show_link_options: { target: '_blank' } }).each do |user|
  user.show_link
  # => <a target="_blank" href="/users/1">ほげ</a>
end

@users.decorate(with: Admin::UserDecorator, context: { show_link_options: { target: '_blank' } }).each do |user|
  user.show_link
  # => <a target="_blank" href="/admin/users/1">ほげ</a>  
end

何が嬉しいのか

前まで、user.admin_show_linkみたいな感じで書いてたのをdecoratorクラス分けて書くようになって、よりオブジェクト指向っぽくなった。
なぜもっと早く気がつかなかったし。

感想、というか愚痴

これDraper::CollectionDecoratorには使えるけど、ActiveRecordのインスタンスに生えるdecorateメソッドにはcontextしか対応していないのでuser.decorate(with: Admin::UserDecorator)みたいなのできない。Admin::UserDecorator.new(user)って書き方。
欲しいなぁと思いつつdecorator側に無いあたり敢えて外してるんだろうかと勘ぐったり。

あと、decorates_associationで関連モデルもまとめてdecorateできるようになってるけど、これ欲しい場合と欲しく無い場合の切り分けにそれぞれクラス作る必要が出てくる。
この辺ももうちょい柔軟に使えたら便利な気もする(もしくはできない方が良いケースが多い?

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?