Подтвердить что ты не робот

Проблемы с сохранением объекта в массиве, проблемы с 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 показывает только название книги, которую я добавил в последний раз.

4b9b3361

Ответ 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