這篇文章將介紹如何使用 Decorator Pattern 的技巧來封裝物件的表達邏輯。

假設有個頁面的部分程式碼如下

%header
  %h3 #{@video.title}
  %span Rating:
  - if @video.rating
    = "#{@video.rating}/5.0"
  - else
    N/A
%p #{@video.description}

若想將上面的程式碼簡化成

%header
  %h3 #{@video.title}
  %span Rating:
  = @video.rating
%p #{@video.description}

一種做法是將顯示 video rating 相關的邏輯放到 Video model 裡面, 但這卻會造成物件的表達邏輯與基本方法混合在一起; 這時候比較好的做法是使用 decorator 來封裝物件的表達邏輯。 下面我們將示範如何透過 Draper gem 來編寫 decorator。

安裝套件

在 Gemfile 加入

gem 'draper'

然後執行 bundle install

使用範例

請在 app/decorators/ 下面新增檔案 video_decorator.rb 並加入內容如下

app/decorators/video_decorator.rb:

class VideoDecorator < Draper::Decorator
  delegate_all # 引入 Video model 的所有方法

  def rating
    object.rating.present? ? "#{object.rating}/5.0" : "N/A"
  end

end

在 VideoController 裡面,使用 decorate 來設定 @video

app/controllers/videos_controller.rb:

class VideosController < ApplicationController

  ... 省略程式碼 ...

  def show
    @video = Video.find_by(slug: params[:id]).decorate
    #@video = Video.find_by(slug: params[:id])
  end

end

之後就可以在 view 裡面使用 @video.rating

%header
  %h3 #{@video.title}
  %span Rating:
  = @video.rating
%p #{@video.description}
Comments

comments powered by Disqus

Published

Category

Web

Tags

Contact