Проблемы с сохранением объекта в массиве, проблемы с Ruby и Rails
Я пытаюсь добавить объект в свой массив, однако массив, как представляется, всегда reset вместо добавления. Что я делаю не так? Я думаю, что это связано с if(defined? libraryshelf) then
. То, что я пытаюсь сделать здесь, - это найти массив или нет (если это первое добавление или нет).
def add_book
@listofbooks ||= Array.new
@listofbooks.push(params[:booktitle])
@listofbooks
respond_to do |format|
format.html { redirect_to(:back) }
format.js
end
end
мой файл add_book.js.erb
alert('<%= @listofbooks %>');
@listofbooks
показывает только название книги, которую я добавил в последний раз.
Ответы
Ответ 1
TL; DR: контроллер не имеет состояния, они просто видят входящий запрос. Чтобы список перечислил текущий запрос, вам нужно сохранить список в сеансе или в базе данных, в зависимости от того, сколько времени вы хотите, чтобы он жил, и других соображений.
Есть и другие проблемы...
Не используйте defined?
для этого, на самом деле, не используйте defined?
для чего-либо. Он не имеет много законных приложений уровня. В этом случае libraryshelf
является локальной переменной, и по ее первой ссылке в методе она всегда не будет определена.
Действуйте непосредственно на @listofbooks
и просто проверьте @listofbooks or @listofbooks.nil?
.
Вот несколько рабочих (я думаю) версий...
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, ваше исправленное сообщение лучше... как указано в TL; DR: поскольку Rails воссоздает объекты контроллера по каждому запросу, вам нужно будет сохранить все, что захотите, в следующий раз в своем сеансе или базе данных.
Оригинальный почтовый вид нас обманул, также каждый раз с помощью метода clobbering @listofbooks
, поэтому мы подумали, что это действительно рубиновый вопрос.
Ответ 2
поскольку вы находитесь в функции libraryshelf
, никогда не будет определяться как локальная переменная. И я предполагаю, что вы используете Ruby 1.8.7, поэтому вы создаете новый массив в области (который вы не сможете увидеть) и присваиваете это @listofbooks
Я предлагаю
def add_book
@listofbooks ||= Array.new
@listofbooks.push(name)
@listofbooks # return the entire list, not the last thing pushed
end
Изменить, чтобы отразить обновленный вопрос
Это проблема с жизненным циклом контроллера. Для каждого запроса создается новый объект контроллера, поэтому любые запросы могут быть удалены между запросами. Вам нужно будет сохранить свои переменные чем-то вроде session[:booklist] = @booklist
, а затем получить его для следующего запроса.
Ответ 3
Глядя на код, кажется, что написанная логика отличается от описания того, что вы хотите. Это то, что я вижу в вашем коде:
# 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
Однако, похоже, вы хотите сделать следующее:
def add_book
# Simply push the new book title on the array of old books
@listofbooks << params[:booktitle]
end