2016-10-10 2 views
0

Ich erhalte Fehler bei einem AJAX-Anruf mit remote: true mit Einheimischen. Hier ist der Fehler:Lokale Probleme in Rails-Anwendung

ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x94db890>:0x9ab41d0>): 

Hier ist mein Code unten:

new.html.erb

<%= form_for(@author) do |f| %> 
    <div class="field"> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %> 
    </div> 
<div class="field"> 
    <%= f.label :age %><br> 
    <%= f.number_field :age %> 
</div> 
<%= link_to "Add Books" , remote: true %> 

<div id = "add_book"></div> 
<%= f.submit %> 

-Controller

def new 
    @author = Author.new 
    @books = @author.books.build 

    respond_to do |format| 
    format.html 
    format.js 
    end 
end 

new.js. Erb

$("#add_book").append(" <%= escape_javascript(render partial: 'addbook', :locals => { :f => f }) %> "); 
+1

Hallo und willkommen zu Stack Overflow. In 'new.js.erb' - woher kommt die Variable' f'? –

+0

von new.html.erb? Entschuldigung, wenn ich falsch lag :( – user3678149

+0

Ich habe eine Erklärung geschrieben, wie Templates funktionieren und warum es nicht geht, finde es von der anderen Vorlage;) Du musst deine js-Vorlage ändern - es wird einfach nicht funktionieren Weg. 'f' existiert nur in der' new.html' Vorlage, nicht in der js Vorlage ... –

Antwort

1

So ... die Art und Weise, dass eine erb Vorlage arbeitet, ist dies:

Rails eine Seite erzeugt, in Ihrem Beispiel, das new, indem Sie durch die new Aktion in der Steuerung sein würde und das Sammeln up alle Variablen (zB author und books).

Dann bekommt es die richtige Vorlage für die Aktion. In dem Fall, wenn Sie zuerst die new Seite öffnen, erhalten Sie das Formular ... richtig? Das kommt von der Vorlage new.html.erb.

So Schienen liest durch die Vorlage und führt den Ruby-Code ... Ersetzen Sie es mit entsprechenden HTML. Dann sendet es den HTML-Code an den Browser.

Bis es an den Browser gesendet wird, gibt es keinen Ruby-Code mehr ... nur html, weil der Browser Ruby nicht versteht, nur html - das ist alles, was gesendet wird.

Jetzt ... der Browser hat ein HTML-Formular, das einige js enthält - das wäre der add books Link - es ist HTML, die einige js, die eine Anfrage an Ihre Rails App sendet ruft.

Die App rails geht dann durch die new Aktion, sammeln die Variablen erneut, aber dieses Mal, es rendern nicht die HTML-Vorlage ... weil es von js aufgerufen wurde. So ergreift es stattdessen die js Vorlage.

An dieser Stelle weiß rails nichts über die HTML-Vorlage. Alles, was in der HTML-Vorlage war, ist schon lange weg - an den Browser gesendet. Alles, was es weiß, ist, was in der js Vorlage ist. Es versucht, den Ruby-Code in der Vorlage zu starten ... und es fragt nach f ... und f existiert nicht in Ihrer js-Vorlage ... so wird es verwirrt und sagt Ihnen, dass es nicht über diese f Sache weiß .

Es spielt keine Rolle, dass es irgendwann in der Vergangenheit eine Form namens f gerendert hat, denn das gehörte zu einer weit entfernten früheren Anfrage, die nicht mehr existiert. Der Browser teilt Rails nicht über f mit, weil er nie davon wusste (das war Teil des Rubins, nicht der HTML-Code, der alles ist, was der Browser jemals gesehen hat). Also ... gibt es keine f. ;)

In diesem Fall - ich bin mir nicht sicher, ob Sie als lokale Variable f überhaupt übergeben müssen. Wenn Sie die Vorlage rendern, die das Formular enthält, müssen Sie kein Formular übergeben, da das Formular bereits gerendert wird. Versuchen Sie einfach, das Partielle darzustellen, ohne Einheimische zu übergehen, und sehen Sie, was passiert ...Wenn Sie einen Fehler bekommen, können wir daran arbeiten.

+0

Ich bekomme viel Verwirrung um 'f' Objekt zu bekommen ** js.erb ** bitte hilf mir auf was ich muss für 'f' Objekt in meiner Anwendung tun: | – user3678149

+0

Ich weiß nicht - woher kam es? –

2

Sie rufen die neue Aktion Ihres Controllers mit remote: true (ein AJAX-Aufruf) auf. Dies hat zur Folge, dass new.js.erb als Antwort zurückgesendet wird - die new.html.erb wird nicht verarbeitet.

Innerhalb new.js.erb Sie haben:

$("#add_book").append(" <%= escape_javascript(render partial: 'addbook', :locals => { :f => f }) %> "); 

Bedeutung es versucht, die AddBook Teil und stellen für sie eine lokale Variable zu machen up, in dem teilweise als f Bezug genommen werden, und es zuweisen der Wert (lokal für new.js.erb) f.

new.js.erb hat die lokale var f und damit Ihren Fehler nicht deklariert.

Um mehr zu unterstützen, müssten wir wissen, was die Intention dieser Variable ist - auf welche Weise benötigt _addbook.html.erb?