控制器中的 render_to_string 部分格式错误
Posted
技术标签:
【中文标题】控制器中的 render_to_string 部分格式错误【英文标题】:render_to_string partial format error in controller 【发布时间】:2012-11-22 16:33:03 【问题描述】:在控制器上运行以下代码时出现以下错误。请注意错误中的:formats=>[:json]
,即使:formats=>[:html]
被传递到render_to_string
我做错了什么?有任何想法吗? 实际上,下面的代码之前运行良好,不确定是什么更改影响了这个错误。 Rails 版本:3.2.8
顺便说一句,模板已经到位:loc/_search_details.html.erb
额外问题:我在哪里可以找到显示哪些参数可以传递给 render_to_string 以及它是如何工作的 api 文档?
错误: ActionView::MissingTemplate(缺少 :locale=>[:en]、:formats=>[:json]、:handlers=>[:erb、:builder、:coffee] 的部分 loc/search_details)。
respond_to do |format|
format.json
@detail_str = render_to_string(:partial => 'loc/search_details', :layout => false, :formats=>[:html], :locals => :beer_results => @beer_results)
@list_str = render_to_string(:partial => 'loc/search_list', :layout => false,:formats=>[:html], :locals => :beer_results => @beer_results)
render :json => :results => @results_hash, :result_details => @detail_str, :result_list => @list_str
end
【问题讨论】:
我认为:format
不是传递给render
的有效参数。
我没有使用 :format,它是 :formats
是的。我也不认为这是一个有效的参数。
【参考方案1】:
以防万一其他人对此感到困惑,如果您要渲染到字符串,则只需在 format.json 块的上下文之外进行渲染。在您的示例中:
respond_to do |format|
@detail_str = render_to_string(:partial => 'loc/search_details', :locals => :beer_results => @beer_results)
@list_str = render_to_string(:partial => 'loc/search_list', :locals => :beer_results => @beer_results)
format.json
render :json =>
:results => @results_hash,
:result_details => @detail_str,
:result_list => @list_str
end
这样,你不必指定格式或布局为假。
【讨论】:
【参考方案2】:以防万一有人遇到同样的问题,这对我有用。
我在使用render_to_string
时收到的错误消息与问题中的完全一样,只是format
不匹配。然而,这并不是问题的真正根源。
问题是我的应用是 i18n-ed 并且在 URL 中给出了区域设置。我的routes.rb
看起来像这样:
Quoties::Application.routes.draw do
scope "(:locale)", locale: /en|pl/ do
# all routes go here
end
end
而我的application_controller.rb
看起来像这样:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_locale
def default_url_options(options=)
locale = I18n.locale
locale = nil if locale == :en
locale: locale
end
def set_locale
parsed_locale = params[:locale] || 'en'
I18n.locale = I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil
end
end
(这是我在互联网某处找到的解决方案的略微调整版本。)
它在大多数地方都运行良好。但是,当我在部分中使用路径帮助器时,结果是“缺少部分”错误的原因,比如
<%= item_path(item) %>
有帮助的解决方法是将上面的行替换为:
<%= item_path(item, locale: params[:locale]) %>
我不知道为什么 default_url_options
在这种情况下不起作用,以及为什么 Rails 会引发如此奇怪的异常。
<% self.formats = [:html, :json] %>
上面建议的解决方案只会使错误消息更清晰,因此至少它更改为在item_path
抛出的“没有路由匹配...”。
【讨论】:
【参考方案3】:见this question 和this issue。由于您正在发出 JSON 请求,因此您的 render_to_string
期望您的部分是 _search_details.json.erb
。您可以提供额外的 JSON 部分、重命名部分或将其添加到部分 <% self.formats = [:json, :html] %>
,或者尝试在该问题的已接受答案中的解决方法。
【讨论】:
你错了,render_to_string
的 :formats => [:html]
参数使得它会首先寻找 _search_details.html.erb
。我自己测试过,它至少在 Rails 3.2.9 中有效。
-- 这个确实有效
我需要 :formats => [:html] 传递给 render_to_string 方法,并在部分中 让它正常工作。 【参考方案4】:
如果你尝试怎么办
render_to_string(:partial => 'loc/search_details.html.erb', :layout => false, :locals => :beer_results => @beer_results)
或者
with_format("html") render_to_string(:partial => 'loc/search_details', :layout => false, :locals => :beer_results => @beer_results)
并添加方法
private
def with_format(format, &block)
old_format = @template_format
@template_format = format
result = block.call
@template_format = old_format
return result
end
来源:How do I render a partial of a different format in Rails?
【讨论】:
第一个解决方案给出了弃用警告:弃用警告:不推荐在模板名称中传递模板处理程序。您可以简单地删除处理程序名称或通过 render :handlers => [:erb] 代替。 您尝试传递 :handlers 还是第二种解决方案对您有用? 传递处理程序没有帮助,还有另一个关于 :formats html 的弃用警告,如果我添加格式,我会回到我拥有的代码并且它不起作用。第二个解决方案看起来像一个肮脏的 hack :) 稍后我会尝试一下。 这是一个肮脏的黑客,但另一方面,您尝试做的事情也有点肮脏,因此该解决方案适合需要 ;) "顺便说一句,模板已经到位:loc/search_details.html.erb" 大声笑,我希望你在那里打错了,你知道部分文件名以下划线开头,我希望 :-)因为我在一个空白的 Rails 应用程序中尝试了你的代码,它工作正常,当然命名正确。【参考方案5】:尝试通过
:format => :html
代替
:formats => [:html]
【讨论】:
:formats
在 4.2.1 中有效,而 :format
则无效。以上是关于控制器中的 render_to_string 部分格式错误的主要内容,如果未能解决你的问题,请参考以下文章
使用 render_to_string 时创建的真实性令牌不同
无法使用 django 的 render_to_string 对单引号 (') 进行编码