【问题标题】:render_to_string partial format error in controller控制器中的 render_to_string 部分格式错误
【发布时间】:2023-03-05 17:42:01
【问题描述】:

在控制器上运行以下代码时出现以下错误。请注意错误中的: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
  • 是的。我也不认为这是一个有效的参数。

标签: ruby-on-rails ruby-on-rails-3


【解决方案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 会引发如此奇怪的异常。

    &lt;% self.formats = [:html, :json] %&gt; 上面建议的解决方案只会使错误消息更清晰,因此至少它更改为在item_path 抛出的“没有路由匹配...”。

    【讨论】:

      【解决方案3】:

      this questionthis issue。由于您正在发出 JSON 请求,因此您的 render_to_string 期望您的部分是 _search_details.json.erb。您可以提供额外的 JSON 部分、重命名部分或将其添加到部分 &lt;% self.formats = [:json, :html] %&gt;,或者尝试在该问题的已接受答案中的解决方法。

      【讨论】:

      • 你错了,render_to_string:formats =&gt; [: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 则无效。
      猜你喜欢
      • 2011-07-20
      • 2017-03-28
      • 2011-10-28
      • 1970-01-01
      • 2015-07-04
      • 2013-09-16
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      相关资源
      最近更新 更多