iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0
自我挑戰組

冒險村-30 Day Ruby on Rails Tips Challenge系列 第 22

冒險村22 - Design Pattern(2) - Presenter

  • 分享至 

  • xImage
  •  

22 - Design Pattern(2) - Presenter

Presenter pattern 的原理是,是 Model-View-Controller(MVC) 架構模式衍生出來的一個部分,主要用於建立使用者的介面接口。 在 MVP 中,Presenter 承擔了 中間人 的功能。在 MVP 中,所有邏輯的部份都會寫在 Presenter 內。事實上,其實與 Decorator 有點相似,通常有些些微的差異,但通常只會選擇兩個其中一個來整理,也沒有一定的通則,主要還是以團隊內的方式為主。

直接來看如何使用:

假設我有一張 Log 的表,裡面 operator 欄位紀錄了 User 誰操作了某項東西,所以紀錄這個 Log,並且知道 Source -> Target 從 A 到 B,這時候想要後台的前端可以看到 Log 紀錄,隨便舉個例子。

Create app/presenters folder

  • user_log_presenter.rb

Add Presenter to Controller

假設 Log 是在 TrackController 內的 show 來顯示,範例如下:

  # frozen_string_literal: true
  class TrackingController < ApplicationController
    def show
      @user_logs = UserLogPresenter.new(user_id)
    end

    # ...
  end

Add app > presenters > user_log_presenter.rb

Enumerable include 近來提供 each 等等方法,

  # frozen_string_literal: true
  class UserLogPresenter
  include Enumerable

    def initialize(user_id)
      @user_id = user_id
    end

    def each(&_block)
      logs.each do |log|
        yield format(log)
      end
    end

    def format(log)
      {
        user:       User.find(log.operator),
        source:     log.source,
        target:     log.target,
        created_at: log.created_at
      }
    end

    def logs
      @logs ||= Log.where(operator: user_id)
    end
  end

View

  @user_logs.each do |log|
    <th><%= log[:user] %></th>
    <th><%= log[:source] %></th>
    <th><%= log[:target] %></th>
    <th><%= log[:created_at] %></th>
  end

註: 想理解兩者的差異也可以參考這篇的比較 Ruby on Rails patterns - decorator vs presenter,雖然目前我也沒有可以完全的分懂 orz

參考資料

My blog


上一篇
冒險村21 - draper
下一篇
冒險村23 - Design Pattern(3) - Builder
系列文
冒險村-30 Day Ruby on Rails Tips Challenge30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言