Ошибка частичного формата render_to_string в контроллере

Я получаю следующую ошибку при запуске ниже кода на контроллере. Обратите внимание на :formats=>[:json] в ошибке, хотя :formats=>[:html] передается в render_to_string

Что я делаю неправильно? Есть идеи? На самом деле, код ниже работал хорошо, не знаю, какие изменения повлияли на эту ошибку. Версия Rails: 3.2.8

btw шаблон определенно на месте: loc/_search_details.html.erb

Бонусный вопрос: где я могу найти документацию api, показывающую, какие параметры могут быть переданы в render_to_string и как это работает?

Ошибка: ActionView:: MissingTemplate (Отсутствуют частичные loc/search_details с помощью {: locale = > [: en],: formats = > [: json],: handlers = > [: erb,: builder,: coffee]}.

  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

Ответ 1

См. этот вопрос и этот вопрос. Поскольку вы делаете запрос JSON, ваш render_to_string ожидает, что ваш частичный номер будет _search_details.json.erb. Вы можете либо предоставить дополнительный JSON частичный, переименовать частичный, либо добавить это в частичный <% self.formats = [:json, :html] %>, либо, альтернативно, попробовать обходной путь в принятом ответе на этот вопрос.

Ответ 2

Что делать, если вы попробуете

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

Источник: Как отредактировать частичный формат в Rails?

Ответ 3

На всякий случай, если кто-то еще обманывает это, если вы передаете строку, вам просто нужно сделать рендеринг вне контекста блока 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

Таким образом, вам не нужно указывать форматы или макет - false.

Ответ 4

Попробуйте передать

:format => :html

Вместо

:formats => [:html]

Ответ 5

На всякий случай у кого-то такая же проблема, вот что сработало для меня.

Сообщение об ошибке, которое было у меня при использовании 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.