【问题标题】:Problems keeping an object in an array, Ruby issues and Rails issues将对象保存在数组中的问题、Ruby 问题和 Rails 问题
【发布时间】:2011-01-29 06:33:21
【问题描述】:

我正在尝试将一个对象添加到我的数组中,但是该数组似乎总是重置,而不是添加。我究竟做错了什么?我认为这与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 只显示我上次添加的书名..

【问题讨论】:

标签: ruby-on-rails ruby arrays


【解决方案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

啊哈,你的修改后的帖子更好了……正如 TL;DR 中所述:因为 Rails 会在每个请求上重新创建控制器对象,所以下次你需要在会​​话或数据库中保留任何你想要的东西。

原来的帖子有点愚弄我们,每次通过该方法都会破坏@listofbooks,所以我们认为这真的是一个红宝石问题。

【讨论】:

  • 感谢您的回复,我尝试了这些,但仍然只显示一个结果。我已经更新了我的代码,以向您展示我添加的内容~
  • OIC -- Rails 在每次 http 请求时都会重新创建控制器对象。如果你想下次看到它们,你必须将它们保存在数据库中。您每次通过原始方法破坏@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

编辑以反映更新后的问题

这是控制器生命周期的问题。对于每个请求,都会实例化一个新的控制器对象,以便在请求之间清除所有 @variables。您需要通过 session[:booklist] = @booklist 之类的方式存储变量,然后为下一个请求检索它。

【讨论】:

  • 为什么是Array.new 而不是[]
  • @Ryan Bigg 前雇主的编码风格。它们的语法不等同于空数组吗?
  • 返回列表本身是个好主意吗?这将允许调用者随心所欲地对其进行变异......
  • @Paul Fisher,这是一个很好的观点,如果不知道更多关于代码 sn-p 的位置或它的适用性,很难说。我认为问题的一部分可能是他的视图调用了这个方法并且只得到一个项目而不是数组。因此评论。
  • 感谢您的回复,但我仍然只显示最后一个结果...我已经编辑了我的代码以反映我所做的更改。
【解决方案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

【讨论】:

猜你喜欢
  • 2015-06-14
  • 2015-06-17
  • 2012-04-05
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
相关资源
最近更新 更多