О шаблоне предъявителя в рельсах. лучший способ сделать это? - PullRequest
5 голосов
/ 12 мая 2010

у меня в модели:

def presenter
   @presenter ||= ProfilePresenter.new(self)
   @presenter
end

ProfilePresenter - это класс, который имеет такие методы, как, get_link (), get_img_url (size), get_sex (), get_relationship_status () и другие методы, которые не имеют отношения к модели, даже с контроллером, но используются несколько раз в представлении.

Так что теперь я использую их следующим образом:

Profile.presenter.get_link
# or
Profile.presenter.get_img_url('thumb') # returns the path of the image. is not used to make a db query

Искренне, я думаю, я упустил реальную концепцию докладчиков ... но это то, что я пытаюсь архивировать, как это можно назвать?

1 Ответ

16 голосов
/ 13 мая 2010

Обычно такие вещи обрабатываются с помощью вспомогательных методов, таких как:

def profile_link(profile)
  profile.link ? content_tag(:a, h(profile.name), :href => profile.link) : 'No profile'
end

К сожалению, вы не можете наложить слой на вспомогательные методы в стиле Presenter, которые расширяют модель во время просмотра. Их нужно вызывать процедурным способом с параметром, своего рода анти-OO.

Подход Presenter не полностью поддерживается в области Rails MVC, поскольку он должен привязываться к представлению, чтобы иметь доступ к различным вспомогательным методам, необходимым для правильной визуализации содержимого, а также информации о сеансе, который может повлиять на представление.

Более надежный подход может заключаться в следующем:

class ProfilePresenter
  def initialize(view, profile)
    @profile = profile
    @view = view

    yield(self) if (block_given?)
  end

  def link
    @profile.link ? @view.content_tag(:a, @view.h(profile.name), :href => @profile.link) : 'No profile'
  end

  def method_missing(*args)
    @profile.send(*args)
  end
end

По вашему мнению, это будет выглядеть примерно так:

<% ProfilePresenter.new(self, @profile) do |profile| %>
<div><%= profile.link %>
<% end %>

Вы можете упростить вызов этого, создав вспомогательный метод, который делает что-то безумное, например:

def presenter_for(model)
  "#{model.class}Presenter".constantize.new(self, model) do |presenter|
    yield(presenter) if (block_given?)
  end
end

Это означает, что у вас гораздо более простой вызов:

<% presenter_for(@profile) do |profile| %>
<div><%= profile.link %>
<% end %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...