Как мне сделать частичку другого формата в Rails? - PullRequest
112 голосов
/ 04 декабря 2008

Я пытаюсь сгенерировать ответ 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' не помогает.

Ответы [ 11 ]

98 голосов
/ 19 февраля 2012

Начиная с Rails 3.2.3, при вызове render: частичный (работает только за пределами блока respond_to).

:formats => [:html]

вместо

:format => 'html'
64 голосов
/ 04 декабря 2008

Что не так с

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

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

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

32 голосов
/ 07 августа 2010

Для Rails 3 блок with_format работает, но он немного другой:

  def with_format(format, &block)
    old_formats = formats
    self.formats = [format]
    block.call
    self.formats = old_formats
    nil
  end
29 голосов
/ 15 мая 2013

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

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

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

Вы можете использовать Rails 4 в Rails 3, создав config / initializer / 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/

29 голосов
/ 04 декабря 2008

Опираясь на ответ Ронинека , я нашел лучшее решение:

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

25 голосов
/ 31 мая 2011

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

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

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

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

16 голосов
/ 22 февраля 2011

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

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

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

def with_format(format, &block)
  old_formats = formats
  begin
    self.formats = [format]
    return block.call
  ensure
    self.formats = old_formats
  end
end
9 голосов
/ 04 декабря 2008

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

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

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

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

<% @template_format = "html" %>
<%= h render(:partial => '/foo/baz') %>
5 голосов
/ 18 октября 2013

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

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

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

2 голосов
/ 22 мая 2012

Похоже, что передача опции formats будет правильно отображать ее в новой версии Rails, по крайней мере, 3.2:

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