Краткая версия ответа:
Ваш сервис должен выдавать себя за локального 'ведущего', а ваш частичный должен делегировать переменные обратно вашему сервису.
Есть более длинный ответ, но сначала немного прочистилось горло ...
Я начал делать бит "рендеринга в любом месте", прежде чем попасть в Rails 5,так что мой подход выглядит немного иначе, чем то, что вы в конечном итоге делаете.Но, возможно, это поможет.
А потом какой-нибудь фон ...
У меня есть модуль (что-то вроде ActsAs::Rendering
), который включает метод экземпляра, называемый render_partial
это выглядит примерно так:
module ActsAs::Rendering
def render_partial(file_name)
file_name = file_name.to_s
render(partial: file_name, locals: {presenter: self})
end
end
Это нечто большее, но я думаю, что это даст вам идею.Важный бит (к которому мы вернемся позже) заключается в том, что self
передается как presenter
.
Затем в моем сервисе я могу сделать что-то вроде:
class BatchMailerService < ApplicationService
def call
render_partial :my_cool_partial
end
def tell_method_something_good
"Tell me that you like it, yeah."
end
end
Я думаю, с Rails 5, вы будете использовать этот FooController.render :action, locals: { ... }
бит.Но, как я уже сказал, я еще не удосужился заняться этим Rails 5, поэтому я не уверен.
Естественно, у меня есть ApplicationService
(ниже app/services
), который выглядит примерно так:
class ApplicationService
include ActsAs::Rendering
attr_accessor *%w(
args
).freeze
class << self
def call(args={})
new(args).call
end
end # Class Methods
#==============================================================================================
# Instance Methods
#==============================================================================================
def initialize(args={})
@args = args
assign_args
end
private
def assign_args
args.each do |k,v|
class_eval do
attr_accessor k
end
send("#{k}=",v)
end
end
end
Сказав все это ...
:my_cool_partial
может выглядеть примерно так:
"my_cool_partial.html.haml"
- @presenter = local_assigns[:presenter] if local_assigns[:presenter]
#tell-me-something-good-container
= @presenter.tell_me_something_good
Теперь, еслиЯ делаю:
BatchMailerService.call
Я получу что-то вроде:
<div id="tell-me-something-good-container">
Tell me that you like it, yeah.
</div>
Таким образом, объекту службы не нужно передавать длинный список locals
.Он просто должен пройти сам по себе, и я просто должен убедиться, что сервисный объект отвечает на любые вызовы, сделанные внутри партиала.