Шаблон JSON Erb не может найти другой частичный HTML
Я пытаюсь получить ответ в формате json, в котором значение html отображается частичным
#projects_Controller.rb
def index
respond_to do |f|
f.json
end
end
# index.json.erb
{
"html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer') %>"
}
Но я получаю следующую ошибку:
ActionView::Template::Error (Missing partial projects/disclaimer with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>
[:json], :locale=>[:en, :en]} in view paths "c:/rails/app/views", "c:/rails/vendor/plugins/more/app/views", "C:/Ruby192/lib/ruby/gems/1.9.1/gems/devise-1.1.8/app/views")
Похоже, что запросы JSON отрисовываются частично с.json.erb в его имени, но не.html.erb, что у меня есть. Есть ли способ для меня, чтобы указать "HTML".
ДОБАВЛЕНО: если запрос 'js', а в index.js.erb я рендую почти такой же код: # index.js.erb
disclaimer = {
"html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer') %>"
}
он находит проекты /disclaimer.html.erb и отображает его правильно. Интересно, почему существует такое несоответствие в том, что если кто-то запрашивает js, то любой частичный рендеринг в его шаблоне будет искать частичное_имя.html.erb, но если один запросит json, то частичный рендеринг будет запрашивать частичный_имя.json.erb?
Спасибо
4 ответа
Понял: все, что нужно, это строка в файле.json.erb <% self.formats = ["html"]%>
Так что полный index.json.erb
<% self.formats = ["html"] %>
disclaimer = {
"html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer',
:content_type => 'text/html'),
:locals => {:localVariable => @localVariable}
%>"
}
Мой ответ похож на ответ Ника. У меня есть следующий помощник для шаблонов json.erb:
# helpers useful for json.erb templates
module JsonHelper
# Same as render but force actionview to look for html templates instead of json.
def render_html(options={}, locals={}, &block)
old_formats = formats
self.formats = [:html] # hack so partials resolve with html not json format
render options, locals, &block
ensure
self.formats = old_formats
end
# json escape a string. For example <%=json "some { string }" %>
def json(value)
raw value.to_json
end
end
Так что теперь я могу писать шаблоны как
{
"html": <%=json render_html(:partial => 'some_partial') %>,
"status": success
}
Это было бы лучше, если бы actionview разрешал рендеринг с content_type, как в примере 23tux (что не работает для меня). Также было бы лучше, если бы только *.html.erb подвергался экранированию html вместо всех файлов *.erb.
Для будущих читателей вы можете передать параметр форматов следующим образом.
= render partial: 'user', locals: {xyz: @xyz}, :formats => [:html]
Я не уверен, правильно ли я вас понял, но, возможно, вы можете поиграть с таким типом контента:
disclaimer = {
"html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer', :content_type => 'text/html'), :locals => {:localVariable => @localVariable} %>"
}
: Localals просто, если вы хотите передать переменную в партиал.