the*_*eld 23 ruby arrays ruby-on-rails
我正在尝试向我的数组添加一个对象,但是数组似乎总是重置,而不是添加.我究竟做错了什么?我认为它与此有关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
Run Code Online (Sandbox Code Playgroud)
我的add_book.js.erb文件
alert('<%= @listofbooks %>');
Run Code Online (Sandbox Code Playgroud)
@listofbooks 只显示我上次添加的书的标题..
Dig*_*oss 34
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
Run Code Online (Sandbox Code Playgroud)
Aha,你的修改后的帖子更好......如TL中所述; DR:因为Rails在每个请求上重新创建控制器对象,你需要在会话或数据库中保留下次想要的任何内容.
原帖一种愚弄我们通过也重挫@listofbooks通过方法每一次,所以我们认为这是一个真正的红宝石问题.
因为你在函数中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
Run Code Online (Sandbox Code Playgroud)
这是控制器生命周期的问题.对于每个请求,将实例化一个新的控制器对象,以便在请求之间清除任何@variables.您将需要通过类似的方式存储变量session[:booklist] = @booklist,然后检索它以用于下一个请求.