开发者

Problems keeping an object in an array, Ruby issues and Rails issues

I'm trying to add an object to my array, however the array see开发者_Go百科ms to always reset, instead of adding. What am I doing wrong? I think it has to do with if(defined? libraryshelf) then, What I'm trying to do here is find out of the array exists or not (if this is the first add or not)..

def add_book
  @listofbooks ||= Array.new
  @listofbooks.push(params[:booktitle])
  @listofbooks
  respond_to do |format|
    format.html { redirect_to(:back) }
    format.js
  end
end

my add_book.js.erb file

alert('<%= @listofbooks %>');

@listofbooks only shows the title of the book I last added..


TL;DR: The controller's are stateless, they just see the incoming request. To have a list outlive the current request, you need to persist the list in either the session or in the database, depending on how long you want it to live and other considerations.

There are some other issues...

Don't used defined? for that, in fact, don't use defined? for anything. It doesn't have many legit application-level uses. In this case, libraryshelf is a local variable, and on its first reference in the method it will always not be defined.

Operate directly on @listofbooks and just check @listofbooks or @listofbooks.nil?.

Here are a few working (I think) versions...

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, your revised post is better ... as noted in TL;DR: because Rails recreates controller objects on each request, you will need to persist anything you want next time around in your session or database.

The original post kind of fooled us by also clobbering @listofbooks every time through the method, so we thought it was really a ruby question.


since you're in a function libraryshelf will never be defined as a local variable. And I'm guessing you are using Ruby 1.8.7 so then you are making a new array in a scope (that you shouldn't be able to see ) and assigning that to @listofbooks

I suggest

def add_book
    @listofbooks ||= Array.new
    @listofbooks.push(name)
    @listofbooks # return the entire list, not the last thing pushed
end

Edit to reflect updated question

This is a problem with the life cycle of the controller. For each request a new controller object is instantiated so any @variables are cleared between requests. You will need to store your variables by something like session[:booklist] = @booklist, then retrieve it for the next request.


Looking at the code, it seems the logic written differs from the description of what you want to happen. This is what I see your code is saying:

# 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

However, it sounds like you want to do the following:

def add_book
   # Simply push the new book title on the array of old books
   @listofbooks << params[:booktitle] 
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜