2011-09-06 9 views
9

Mi sono imbattuto in una stranezza che non riesco a spiegare per quanto riguarda Rails 3 e rendering parziali con layout (dal controller). Spero che qualcuno possa fornire un piccolo spaccato di cosa sta succedendo.Rails 3 vs 2.3.5 rendono le stranezze con: partial e: layout

Prima di tutto, chiameremo questo controller un controller "legacy". È in circolazione da molto tempo e sta facendo un sacco di cose sbagliate, ma non sto cercando di refactoring a questo punto, quindi sto cercando di trovare modi per lavorare con quello che abbiamo.

L'azione new è qualcosa di simile (nel BarsController)

def new 
    if something 
    render :partial => "foo", :layout => "bars" 
    elsif something_else 
    render :partial => "foo2", :layout => "bars" 
    elsif something_else_else 
    render :partial => "foo3", :layout => "bars" 
    else 
    render :partial => "foo4", :layout => "bars" 
end 

Ora, in Rails 2.3.5, questo ha funzionato bene. Renderà il partial appropriato all'interno del layout appropriato - Mi rendo conto che l'opzione di layout è ridondante qui come sarebbe predefinita per il layout delle barre a prescindere. Quando abbiamo trasferiti in Rails 3.0.x, abbiamo iniziato a ricevere gli errori come segue:

Missing partial layouts/bars with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html] 

Chiaramente il file layouts/bars.html.erb è ed è sempre stato lì, così non ho potuto capire. Sono stato in grado di eseguire il rendering con :layout => false, ma ovviamente non funzionava. Alla fine ho capito che se faccio una delle seguenti, funziona:

1) Rinominare il mio layout per _bars.html.erb invece di bars.html.erb e:

render :partial => 'foo2', :layout => 'bars'

2) tengo il mio layout bars.html.erb (cosa voglio) e:

render '_foo2' # :partial option is redundant here anyway


Sembra che utilizzando l'opzione: partial anziché la stringa come primo parametro causi alle rotaie l'applicazione della convenzione _name.html.erb sia allo partial AND allo layout. Se inserisco il carattere di sottolineatura per conto mio, ricade sul comportamento che mi aspettavo, il quale non antepone un _ al nome del layout.

Qualcuno sa perché questo è il caso?


EDIT Va bene, non so come ho perso questo ... ma qui c'è qualcosa nella documentazione che fanno menzione di questo. Sembra che sia in giro dal 2.3.8, forse è stato fatto diversamente in 2.3.5 (su cosa stavamo girando)?

3.4.3 Layout parziali

A parziale può usare un proprio file di layout, proprio come una vista può utilizzare un layout . Ad esempio, è possibile chiamare un parziale come questo:

<% = rendere "link_area",: layout => "Graybar" %> Questo sarebbe cercare un parziale _link_area.html.erb di nome e di renderlo con il layout _graybar.html.erb.Si noti che i layout per Partial seguono la stessa denominazione di underscore del primo come parziali regolari e sono collocati nella stessa cartella con il parziale a cui appartengono (non nella cartella di layout principale ).


+0

Ciò richiederebbe più codice mod se si passano i parametri ai parziali, tramite: oggetto o: locali poiché quelli non funzionano con i modelli. Vorrei che non avessero cambiato il comportamento ... – farhadf

risposta

15

Ecco la mia risposta alla domanda sulla base di quello che ho modificato sopra:

Dal Rails 2.3.8, sembrerebbe come se il comportamento predefinito durante il rendering parziale con render :partial => 'foo', :layout => 'bars' è aspettarsi un file "layout parziale" e un file di visualizzazione parziale. In questo caso si aspettano

app/views/_foo.html.erb così come app/views/layouts/_bars.html.erb

Per chiunque si verifichi questo problema l'aggiornamento da Rails 2.3.5, ecco la soluzione che ho trovato per avere il minor numero di impatto:

render '_foo', :layout => 'bars'

Questa soluzione non presuppone il rendering parziale e pertanto non prevede un layout parziale. L'altra opzione sarebbe quella di duplicare il vostro layout per

app/views/layouts/_bars.html.erb

e utilizzando

render :partial => 'foo', :layouts => 'bars'

ma che si traduce in una certa duplicazione del codice.

ROTAIE 2.3.8+ DOC PER QUANTO RIGUARDA QUESTO:

3.4.3 Layout parziali

Un parziale può usare il proprio file di layout, proprio come una vista può utilizzare un layout . Ad esempio, è possibile chiamare un parziale come questo:

<% = rendere "link_area",: layout => "Graybar" %> Questo sarebbe cercare un parziale _link_area.html.erb di nome e di renderlo con il layout _graybar.html.erb. Si noti che i layout per Partial seguono la stessa denominazione di underscore del primo come parziali regolari e sono collocati nella stessa cartella con il parziale a cui appartengono (non nella cartella di layout principale ).

+0

molto utile, grazie per aver condiviso! – Rubytastic

Problemi correlati