Ruby on Rails
장식 패턴
수색…
비고
Decorator 패턴을 사용하면 기본 객체에 영향을 미치지 않고 상황에 맞는 방식으로 객체의 동작을 추가하거나 수정할 수 있습니다.
이것은 stdlib를 사용하는 일반 Ruby 또는 Draper 와 같은 인기있는 보석을 통해 얻을 수 있습니다.
SimpleDelegator를 사용하여 모델 장식하기
대부분의 Rails 개발자는 템플릿 자체에서 모델 정보를 수정하는 것으로 시작합니다.
<h1><%= "#{ @user.first_name } #{ @user.last_name }" %></h1>
<h3>joined: <%= @user.created_at.in_time_zone(current_user.timezone).strftime("%A, %d %b %Y %l:%M %p") %></h3>
많은 양의 데이터가있는 모델의 경우,이 작업은 신속하게 성 가시고 하나의 템플릿에서 다른 템플릿으로 로직을 복사하여 붙여 넣을 수 있습니다.
이 예제는 stdlib의 SimpleDelegator
를 사용합니다.
SimpleDelegator
객체에 대한 모든 요청은 기본적으로 부모 객체에 전달됩니다. 프리젠 테이션 로직으로 모든 메소드를 겹쳐 쓰거나이 뷰에 고유 한 새 메소드를 추가 할 수 있습니다.
SimpleDelegator
는 위임 할 객체를 설정하는 __getobj__
과 해당 객체를 가져 오는 __setobj__
두 가지 메소드를 제공합니다.
class UserDecorator < SimpleDelegator
attr_reader :view
def initialize(user, view)
__setobj__ @user
@view = view
end
# new methods can call methods on the parent implicitly
def full_name
"#{ first_name } #{ last_name }"
end
# however, if you're overriding an existing method you need
# to use __getobj__
def created_at
Time.use_zone(view.current_user.timezone) do
__getobj__.created_at.strftime("%A, %d %b %Y %l:%M %p")
end
end
end
일부 데코레이터는 이런 동작을 철저히 분석하기 위해 마술에 의존하지만, 페이지에서 객체를 초기화하여 프리젠 테이션 로직이 어디에서 오는지를 분명히 할 수 있습니다.
<% user = UserDecorator.new(@user, self) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>
뷰 객체에 대한 참조를 데코레이터로 전달함으로써 프레젠테이션 로직을 포함하지 않고 나머지 뷰 헬퍼에 액세스 할 수 있습니다.
이제 뷰 템플릿은 데이터를 페이지에 삽입하는 것과 관련이 있으며 훨씬 더 명확합니다.
Draper를 사용하여 모델 꾸미기
Draper는 관습에 따라 자동으로 모델을 데코레이터와 일치시킵니다.
# app/decorators/user_decorator.rb
class UserDecorator < Draper::Decorator
def full_name
"#{object.first_name} #{object.last_name}"
end
def created_at
Time.use_zone(h.current_user.timezone) do
object.created_at.strftime("%A, %d %b %Y %l:%M %p")
end
end
end
ActiveRecord 객체를 포함하는 @user
변수가 주어지면 #decorate
에서 #decorate
를 호출하거나 @user
하려면 Draper 클래스를 지정하여 데코레이터에 액세스 할 수 있습니다.
<% user = @user.decorate %><!-- OR -->
<% user = UserDecorator.decorate(@user) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>