我需要一个html字符串(类似"<html><body>Hello World</body></html>"
)用于传真目的。
我把它写进了一个单独的动词文件:views/orders/_fax.html.erb
,并尝试渲染动作中的动词:html_data = render(:partial => 'fax')
。
下面是引起问题的控制器部分:
respond_to do |format|
if @order.save
html_data = render(:partial => 'fax')
response = fax_machine.send_fax(html_data)
......
format.html { redirect_to @order, notice: 'Order was successfully created.' }
format.json { render json: @order, status: :created, location: @order }
else
format.html { render action: "new" }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
它给了我一个AbstractController::DoubleRenderError,如下所示:
AbstractController::DoubleRenderError in OrdersController#create
Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
如何解决这个问题?
如果您只需要呈现的HTML,而不需要控制器的任何功能,您可以尝试直接在helper类中使用ERB,例如:
module FaxHelper
def to_fax
html = File.open(path_to_template).read
template = ERB.new(html)
template.result
end
end
ERB文档对此有更详细的解释。
编辑要从控制器获取实例变量,将绑定传递到result
调用,例如:
# controller
to_fax(binding)
# helper class
def to_fax(controller_binding)
html = File.open(path_to_template).read
template = ERB.new(html)
template.result(controller_binding)
end
注意:我从来没有这样做过,但它似乎是可行的:)
使用#render_to_string方法
它的工作方式与典型的渲染方法相同,但当你需要向json响应添加一些模板化的HTML时,它会很有用
http://apidock.com/rails/ActionController/Base/render_to_string如果你不想转义html,只需调用。html_safe:
"<html><body>Hello World</body></html>".html_safe
关于您的错误,请发布您的OrdersController -看起来您在创建操作中多次调用渲染或重定向。
(顺便说一句,以防万一你正在尝试-你不能在控制器中渲染局部-你只能在视图中渲染局部)
编辑:是的,你的问题是你试图在控制器动作中渲染部分。您可以使用after_create
回调来设置和发送传真-尽管您不会想要使用部分(因为它们用于视图)。http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
编辑:对于你的传真问题,你可以创建一个普通的Ruby类,看看这个来自Yehuda的优秀建议:https://stackoverflow.com/a/1071510/468009
原因是您不能在同一时间内多次呈现或重定向同一个操作。
但是在你的代码中,你有render
和redirect
。我认为在你的控制器中,你可以只使用渲染,假设你不需要任何json输出。
试试这个
def create
@order.save
render(:partial => 'fax')
end
我还没有测试过这个,但我猜你明白了:),并考虑一种方法来处理错误(以防order没有保存)。