2009-12-02 17 views
6

Ecco la chiamata nel file application.html.erb:problema di rendering parziale del layout dell'applicazione (Rails)

<%= render :partial => 'tasks/_new' %> 

Ecco il parziale in fase di rendering (_new.html.erb):

<% form_for @task do |f| -%> 
    <%= f.text_field :body %> 
    <%= submit_tag "Submit" %> 
<% end -%> 

Ecco il metodo nel ' controller delle attività:

def new 
    @task = Task.new 

    respond_to do |format| 
    format.html # new.html.erb 
    format.xml { render :xml => @task } 
    end 
end 

Ecco il messaggio di errore che continuo a ricevere:

Missing template tasks/__new.erb in view path app/views 

e si dice che l'errore è in questa linea:

<%= link_to "tasks", tasks_path %> <%= render :partial => 'tasks/_new' %> 

Il file si trova nella directory giusta. La cosa strana è che nel nome del file c'è un _ in piùnell'errore. Quando mi arrendo e rinominare il parziale __new.erb, ecco l'errore che ottengo:

Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id 

E dice l'errore è in questa linea:

<% form_for @task do |f| -%> 

avevo anche provato senza la _ in il codice, come suggerito da Petros, ma restituisce lo stesso errore di sopra, Called id for nil….

Cosa sta succedendo?

risposta

9

Non è necessario il _ nel codice. Dovrebbe essere:

<%= render :partial => 'tasks/new' %> 

Il primo errore è perché non è necessario inserire _ all'interno del parametro: partial. Rails si prende cura di questo. Ecco perché ottieni il doppio __ perché Rails ne metterà uno per te.

Il secondo errore è il tuo vero problema. L'errore suggerisce che @task è nullo. Questo è vero perché il partial conosce solo ciò che la vista del contenitore conosce e la tua vista in quel particolare momento non ha chiamato l'azione dal controller appropriato. Come tu (Baby Diego) hai già scoperto e indicato in uno dei tuoi commenti qui sotto, dovevi creare un'istanza di un'attività nel tuo parziale. Non so se ci sia una soluzione più elegante, ma forse qualcuno potrebbe suggerire qualcosa di meglio in futuro.

Grazie a MattMcKnight per informarci che il parziale stesso conosce solo ciò che sa la vista del contenitore.

+0

Siamo spiacenti, avrei dovuto specificare. Ci ho provato anche io. Ha restituito l'errore "chiamato id per nil". Sistemerò l'OP. –

+0

Puoi provare <% = render: partial => 'tasks/new', locals => {: task => @task}%> ... Potrebbe essere necessario cambiare @task in task nel tuo partial o aggiungere codice a la parte superiore del fare parziale <% @task = task if @task == nil%> – Petros

+0

Ho provato a farlo funzionare ma non ho potuto. Mi hai aiutato a capire che il problema era che non c'era alcuna istanza di '@task' che raggiungesse effettivamente il layout dell'applicazione, poiché è associato al controller delle attività, quindi ho provato "<% form_for Task.new do | f | -%>" e ha funzionato. Ma sembra un po 'come un hack. È l'approccio giusto? –

4

Petros identifica correttamente il primo problema: non è necessario il trattino di sottolineatura nella chiamata parziale. La seconda cosa da sapere sui partial è che non chiamano il metodo controller, ma fanno semplicemente riferimento alla vista. Pertanto, è necessario impostare l'oggetto @task in ogni azione che utilizza tale partial o chiamare semplicemente Task.new nel partial. Quando ho un parziale in un layout in situazioni simili, di solito lo carico con JavaScript, così posso chiamare l'azione.

+0

Lo sto chiamando dal layout dell'applicazione, l'azione che usa il partial sarebbe qualcosa nel controller dell'applicazione, giusto? A parte questo, io usando "<% form_for Task.new do | f | -%>" invece non è un hack? –

+0

Grazie MattMcKnight per averci informato che un parziale conosce solo ciò che sa la vista del contenitore. Ho modificato la mia risposta per essere più accurata. – Petros

+0

Non è un trucco per chiamare un metodo di classe su un modello. Chiamando <% tasks = Task.find (: all,: condizioni => "complete = false")%> nel partial sarebbe vicino a un hack. Penso che un concetto chiave che alcune persone non capiscono in Rails è che viene chiamata una sola azione (cioè il metodo controller). – MattMcKnight

1

Se le esigenze parziali di conoscere una variabile nel file chiamata Erb, è possibile passare in questo modo:

<%= render partial: "tasks/new", locals: { task: @task } %> 

E nel file di app/views/tasks/_new.html.erb, fare riferimento alla variabile in questo modo:

<% form_for task do |f| %> 
    <%= f.text_field :body %> 
    <%= submit_tag "Submit" %> 
<% end %> 

Cioè, senza @. (Il codice a: b è solo una forma più conveniente di :a => b.)

Mi chiedo, però, perché si desidera utilizzare partial in file application.html.erb? Suppongo che intenda il file generato da Ruby app/views/layouts/application.html.erb, che dovrebbe essere usato come un file di layout contenente elementi comuni a tutte le pagine dell'applicazione, non per la logica aziendale. Forse il file che devi chiamare parziale è app/views/tasks/index.html.erb?

Problemi correlati