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

Я пытаюсь создать ответ JSON, который включает некоторый HTML. Таким образом, у меня есть /app/views/foo/bar.json.erb:

{
  someKey: 'some value',
  someHTML: "<%= h render(:partial => '/foo/baz') -%>"
}

Я хочу, чтобы он отображал /app/views/foo/_baz.html.erb, но он будет отображать только /app/views/foo/_baz.json.erb. Передача :format => 'html' не помогает.

Ответ 1

Основываясь на ответе roninek, я нашел лучшее решение для следующего:

в/app/helpers/application.rb:

def with_format(format, &block)
  old_format = @template_format
  @template_format = format
  result = block.call
  @template_format = old_format
  return result
end

В/app/views/foo/bar.json:

<% with_format('html') do %>
  <%= h render(:partial => '/foo/baz') %>
<% end %>

Альтернативным решением было бы переопределить render, чтобы принять параметр :format.

Я не мог получить render :file для работы с местными жителями и без какой-либо неудобства пути.

Ответ 2

Начиная с Rails 3.2.3 при вызове render: partial use

:formats => [:html]

вместо

:format => 'html'

Ответ 3

Что случилось с

render :partial => '/foo/baz.html.erb'

? Я просто попробовал это, чтобы частично отобразить HTML ERB внутри шаблона построителя Atom, и он работал нормально. Не нужно возиться с глобальными переменными (да, я знаю, что они "@" перед ними, но это то, что они есть).

Ваш with_format &block подход <класs > хорош, хотя и имеет то преимущество, что вы указываете только формат, тогда как простой подход определяет механизм шаблона (ERB/​​builder/и т.д.).

Ответ 4

Для Rails 3 работает блок with_format, но он немного отличается:

  def with_format(format, &block)
    old_formats = formats
    self.formats = [format]
    block.call
    self.formats = old_formats
    nil
  end

Ответ 5

Rails 4 позволит вам передать параметр формата. Таким образом, вы можете сделать

render(:partial => 'form', :formats => [:html])} 

Обратите внимание, что вы можете сделать что-то подобное в Rails 3, но он не передаст этот формат для любых подчастичных (если форма вызывает другие частичные).

Вы можете использовать Rails 4 в Rails 3, создав config/initializers/renderer.rb:

class ActionView::PartialRenderer
  private
  def setup_with_formats(context, options, block)
    formats = Array(options[:formats])
    @lookup_context.formats = formats | @lookup_context.formats
    setup_without_formats(context, options, block)
  end

  alias_method_chain :setup, :formats
end

См. http://railsguides.net/2012/08/29/rails3-does-not-render-partial-for-specific-format/

Ответ 6

В Rails 3 View имеет массив форматов, что означает, что вы можете настроить его для поиска [: mobile,: html]. Настройка, по умолчанию будет искать: мобильные шаблоны, но вернуться к: html шаблонам. Эффекты установки этого будут каскадироваться во внутренние части.

Лучший, но все же недостаток, который я мог бы найти, чтобы установить это, заключалось в том, чтобы поместить эту строку вверху каждого полного мобильного шаблона (но не частичного).

<% self.formats = [:mobile, :html] %>

Недостатком является то, что вы должны добавить эту строку к нескольким шаблонам. Если кто-нибудь знает способ установить это один раз, из application_controller.rb, я хотел бы это узнать. К сожалению, это не работает, чтобы добавить эту строку в ваш макет мобильного устройства, потому что шаблоны отображаются перед макетом.

Ответ 7

Просто уточняю, что написал zgchurch:

  • учет исключений
  • возвращает результат вызываемого блока

Думал, что это может быть полезно.

def with_format(format, &block)
  old_formats = formats
  begin
    self.formats = [format]
    return block.call
  ensure
    self.formats = old_formats
  end
end

Ответ 8

У вас есть два варианта:

1) использовать render :file

render :file => "foo/_baz.json.erb"

2) измените формат шаблона на html, установив переменную @template_format

<% @template_format = "html" %>
<%= h render(:partial => '/foo/baz') %>

Ответ 9

У меня был файл с именем "api/item.rabl", и я хотел отобразить его из представления HTML, поэтому мне пришлось использовать:

render file: 'api/item', formats: [:json]

(file, потому что файл не имеет подчеркивания в имени, formats, а не format (и передает и массив))

Ответ 10

Кажется, что передача параметра formats будет корректно отображать его в новой версии Rails, по крайней мере 3.2:

{
  someKey: 'some value',
  someHTML: "<%= h render('baz', formats: :html) -%>"
}

Ответ 11

Я столкнулся с этим потоком, когда пытался обработать частичный XML в другом файле вида xml.builder. Ниже приведен хороший способ сделать это.

xml.items :type => "array" do
    @items.each do |item|
        xml << render(:partial => 'shared/partial.xml.builder', :locals => { :item => item })
    end
end

И да... Полное имя файла здесь тоже работает...