我遇到了在控制器(服务/ lib目录下的类)之外呈现HTML模板的情况,我经历了https://api.rubyonrails.org/classes/ActionController/Renderer.html
@template = ApplicationController.render(
template: 'template',
layout: mailer_template,
)
是否将所有实例变量传递给“仅呈现方法”选项以获取对view(html模板)中的实例变量的访问权限,或者是否具有任何其他可访问所有实例变量的配置?。
FooController.render :action, locals: { ... }, assigns: { ... }
如果确实传递了模板/布局文件中正在使用的所有实例变量,则在添加新变量时需要检查所有时间。我已经参考了动作控制器和动作视图的流程,并得到了这个How are Rails instance variables passed to views?,对于非控制器类,我如何拥有这个流程?
答案 0 :(得分:0)
答案的简短版本是:
您的服务应作为“演示者”本地传递,而您的部分应将变量委派回您的服务。
答案更长,但首先要清理嗓子...
在进入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
。它本身必须传递,而我只需要确保服务对象能够响应在部分对象内进行的所有调用。