Хорошо. Вот гайка этого. (Это неполный код, предназначенный для указания направления, я много удалил, поэтому вам придется заполнить пробелы.)
Сначала я создаю модуль с именем ActsAs::Rendering
. Это обеспечивает экземпляр ActionView::Base
, который является ключом для рендеринга в любом месте.
module ActsAs::Rendering
private
def action_view() @action_view ||= new_action_view end
def new_action_view
av = ActionView::Base.new
av.view_paths = ActionController::Base.view_paths
av.class_eval do
include Rails.application.routes.url_helpers
include ApplicationHelper
end
av
end
def method_missing(meth, *params, &block)
if action_view.respond_to?(meth)
action_view.send(meth, *params, &block)
else
super
end
end
def render_partial(file_ref)
render(partial: "#{file_ref}", locals: {presenter: self})
end
end
Затем я создаю PresenterBase
, который включает ActsAs::Rendering
:
def PresenterBase
include ActsAs::Rendering
class << self
def present(args={})
new(args).present
end
end # Class Methods
#==============================================================================================
# Instance Methods
#==============================================================================================
def initialize(args)
@args = args
end
private
end
А теперь я создаю Presenter
класс, который реализует present
.
def FooPresenter < PresenterBase
#==============================================================================================
# Instance Methods
#==============================================================================================
def present
render_partial 'path/to/foo/partial'
# or do a lot of other cool stuff.
end
end
И все мои взгляды начинаются с:
- @presenter = local_assigns[:presenter] if local_assigns[:presenter]
И теперь у представления больше нет доступа ни к чему, кроме его докладчика.
* ПРИМЕЧАНИЕ *
Еще немного, но мне нужно бежать. Я обновлю позже.