Come si esegue il rendering di una parte di un formato diverso in Rails?
-
19-08-2019 - |
Domanda
Sto cercando di generare una risposta JSON che includa un po 'di HTML. Quindi, ho /app/views/foo/bar.json.erb
:
{
someKey: 'some value',
someHTML: "<%= h render(:partial => '/foo/baz') -%>"
}
Voglio renderlo /app/views/foo/_baz.html.erb
, ma renderizzerà solo /app/views/foo/_baz.json.erb
. Passando : format = > 'html'
non aiuta.
Soluzione 5
Basandosi su di roninek risposta , ho trovato la soluzione migliore per essere la seguente:
in /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
In /app/views/foo/bar.json:
<% with_format('html') do %>
<%= h render(:partial => '/foo/baz') %>
<% end %>
Una soluzione alternativa sarebbe quella di ridefinire render
per accettare un parametro : format
.
Non sono riuscito a ottenere render: file
per lavorare con la gente del posto e senza un po 'di complicità nel percorso.
Altri suggerimenti
A partire da Rails 3.2.3, quando si chiama render: partial (funziona solo al di fuori del blocco respond_to
).
:formats => [:html]
anziché
:format => 'html'
Cosa c'è che non va
render :partial => '/foo/baz.html.erb'
? Ho appena provato questo per rendere parziale un ERB HTML dall'interno di un modello di generatore Atom e ha funzionato bene. Non è necessario scherzare con le variabili globali (sì, so che hanno " @ " davanti a loro, ma è quello che sono).
Il tuo
Per Rails 3, il blocco with_format funziona, ma è un po 'diverso:
def with_format(format, &block)
old_formats = formats
self.formats = [format]
block.call
self.formats = old_formats
nil
end
Rails 4 ti permetterà di passare un parametro di formati. Quindi puoi farlo
render(:partial => 'form', :formats => [:html])}
Nota che puoi fare qualcosa di simile in Rails 3 ma non passerebbe quel formato a nessun sub parziale (se il modulo chiama altri parziali).
Puoi avere l'abilità di Rails 4 in Rails 3 creando 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
Vedi http: // railsguides.net/2012/08/29/rails3-does-not-render-partial-for-specific-format/
In Rails 3, View ha un array di formati, il che significa che puoi impostarlo per cercare [: mobile,: html]. L'impostazione predefinita è la ricerca di: modelli mobili, ma ricadere su: modelli html. Gli effetti dell'impostazione di questo precipiteranno in parti interne.
Il modo migliore, ma ancora imperfetto, che ho potuto trovare per impostare questo è stato quello di mettere questa linea nella parte superiore di ogni modello mobile completo (ma non parziale).
<% self.formats = [:mobile, :html] %>
Il difetto è che devi aggiungere quella linea a più template. Se qualcuno conosce un modo per impostarlo una volta, da application_controller.rb, mi piacerebbe saperlo. Sfortunatamente, non funziona per aggiungere quella linea al layout del tuo dispositivo mobile, perché i modelli sono resi prima del layout.
Sto solo elaborando ciò che zgchurch ha scritto:
- prendendo in considerazione le eccezioni
- restituendo il risultato del blocco chiamato
Ho pensato che potesse essere utile.
def with_format(format, &block)
old_formats = formats
begin
self.formats = [format]
return block.call
ensure
self.formats = old_formats
end
end
Hai due opzioni:
1) usa render: file
render :file => "foo/_baz.json.erb"
2) cambia il formato del modello in html impostando la variabile @template_format
<% @template_format = "html" %>
<%= h render(:partial => '/foo/baz') %>
Avevo un file chiamato 'api / item.rabl' e volevo renderizzarlo da una vista HTML, quindi ho dovuto usare:
render file: 'api / item', formati: [: json]
( file
perché il file non ha un carattere di sottolineatura nel nome, formati
e non format
(e passa e array))
Sembra che il passaggio di un'opzione formati
lo renda correttamente nella versione più recente di Rails, almeno 3.2:
{
someKey: 'some value',
someHTML: "<%= h render('baz', formats: :html) -%>"
}
Mi sono imbattuto in questo thread quando stavo provando a rendere un XML parziale in un altro file di visualizzazione xml.builder. Di seguito è riportato un bel modo per farlo
xml.items :type => "array" do
@items.each do |item|
xml << render(:partial => 'shared/partial.xml.builder', :locals => { :item => item })
end
end
E sì ... Anche il nome file completo funziona qui ...