J'essaie d'ajouter un objet à mon tableau, mais le tableau semble toujours se réinitialiser, au lieu de l'ajouter. Qu'est-ce que je fais mal? Je pense que cela a à voir avec if(defined? libraryshelf) then
, ce que j'essaie de faire ici est de découvrir que le tableau existe ou non (si c'est le premier ajout ou non) ..
def add_book
@listofbooks ||= Array.new
@listofbooks.Push(params[:booktitle])
@listofbooks
respond_to do |format|
format.html { redirect_to(:back) }
format.js
end
end
mon fichier add_book.js.erb
alert('<%= @listofbooks %>');
@listofbooks
ne montre que le titre du livre que j'ai ajouté en dernier ..
TL; DR: Les contrôleurs sont apatrides, ils ne voient que la requête entrante. Pour qu'une liste survive à la demande actuelle, vous devez la conserver dans la session ou dans la base de données, en fonction de la durée de vie et d'autres considérations.
Il y a d'autres problèmes ...
Ne pas utiliser defined?
pour cela, en fait, n'utilisez pas defined?
pour rien. Il n'a pas beaucoup d'utilisations légitimes au niveau de l'application. Dans ce cas, libraryshelf
est une variable locale, et à sa première référence dans la méthode, elle ne sera pas toujours définie.
Opérez directement sur @listofbooks
et vérifiez simplement @listofbooks or @listofbooks.nil?
.
Voici quelques versions qui fonctionnent (je pense) ...
def add_book name
@listofbooks = [] unless @listofbooks
@listofbooks << name
end
def add_book name
@listofbooks ||= []
@listofbooks << name
end
def add_book name
@listofbooks = @listofbooks.to_a.Push name # yes, works even if @listofbooks.nil?
end
Aha, votre publication révisée est meilleure ... comme indiqué dans TL; DR: parce que Rails recrée les objets de contrôleur à chaque demande, vous devrez persister tout ce que vous voulez la prochaine fois dans votre session ou base de données.
Le message d'origine nous a dupés en aussi clobbering @listofbooks
à chaque fois dans la méthode, nous avons donc pensé que c'était vraiment une question Ruby.
puisque vous êtes dans une fonction libraryshelf
ne sera jamais défini comme une variable locale. Et je suppose que vous utilisez Ruby 1.8.7 donc vous créez un nouveau tableau dans une portée (que vous ne devriez pas pouvoir voir) et l'assignez à @listofbooks
Je suggère
def add_book
@listofbooks ||= Array.new
@listofbooks.Push(name)
@listofbooks # return the entire list, not the last thing pushed
end
Il s'agit d'un problème avec le cycle de vie du contrôleur. Pour chaque demande, un nouvel objet contrôleur est instancié afin que toutes les @variables soient effacées entre les demandes. Vous devrez stocker vos variables par quelque chose comme session[:booklist] = @booklist
, puis récupérez-le pour la prochaine demande.
En regardant le code, il semble que la logique écrite diffère de la description de ce que vous voulez faire. Voici ce que je vois votre code dit:
# Create an Empty Array, assign it to @listofbooks
@listofbooks ||= Array.new
# Add the name of a book from a request parameter
@listofbooks.Push("Agile Development with Rails")
# At this point @listofbooks only contains 1 element; we started with
# an empty array and added 1 element through the request parameter
Cependant, il semble que vous souhaitiez effectuer les opérations suivantes:
def add_book
# Simply Push the new book title on the array of old books
@listofbooks << params[:booktitle]
end