【rails】viewに関する処理はActiveDecoratorを使う

※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。

viewに関わるコードはmodelに書かない

前回、view表示に関わるコードをhelperに書いた

viewに関するコードはmodelにも書かれているので、今回はActiveDecoratorを使っていく

viewに関するコードをmodelに書くデメリット
  • 行数が多くなりすぎて、管理がしにくくなる
  • 見た目に関するコードはmodelに書くべきじゃない
    「helperに書くべき」という、railsの思想に反してしまう

ActiveDecoratorを使うと、直感的でわかりやすいコードを書くことができる


ActiveDecoratorをインストールする

gemfileに書き足し、インストールする

gem 'active_decorator'
bundle install

decoratorを作成する

rails g decorator user

これでuserに関するdecoratorが作成されるので、サーバーを再起動rails sする


viewに関するコードをそのまま移していく

controllerで使う可能性のあるコードはmodelに置いておく

app/decorators/user_decorator.rbが生まれているので開く

user.rbからそのまま移していく

module UserDecorator
  def display_name
    profile&.nickname || self.email.split('@').first
  end

  def avatar_image
    if profile&.avatar&.attached?
      profile.avatar
    else
      'default-avatar.png'
    end
  end
end

article.rbからも同じように移していく

module ArticleDecorator
  def display_created_at
    I18n.l(created_at, format: :default)
  end

  def author_name
    user.display_name
  end

  def like_count
    likes.count
  end
end

ActiveDecoratorとdeviceは相性が悪い?

上記のコードだけだとavatar_imageについて「undefined method `avatar_image’」のエラーが出る

これは、deviceのcurrent_userをActiveDecoratorが検知できないため発生する

そのため、app/controllers/application_controller.rbに定義を追加する

class ApplicationController < ActionController::Base
  def current_user
    ActiveDecorator::Decorator.instance.decorate(super) if super.present?
    super
  end
end

super(継承元)である、deviceのcurrent_userが存在(present?)したとき、current_userdecorateして、current_userを返す

(初心者には???すぎるけど、エラーは解決できた)

#DAY4