session question..

Hi, I'm reading Agile Web Development with Rails 2nd Edition. Here, to save items a customer has selected, it has used session and a "Cart" class which is a model but doesn't have 'carts' table in the database. In the class it has defined method to add selected items as:

database. So I've also made Cart class but I have 'carts' table as well. So, I've used <%form_for :cart ....%> to get all the details from the form in one object and done @cart=find_cart(params[:cart]) and find_cart method as: (I'm not sure if its right way. I even don't know what exactly is happening between sessions table which was created via db:session:create and my 'carts' table.) --------------------------------------------------------------------------- ----- def find_cart(cartobj) session[:cart] ||= Cart.new(cartobj) end

If carts are saved in the database I would just save its id in the session. If this is all you're using here you're not actually saving anything in the carts table at all.

--------------------------------------------------------------------------- -----

so far so good, details got saved but when it came to emptying the cart list, I'm confused what to do. Author has done it as:

Your would just retrieve the cart object and destroy it.

Fred

Frederick Cheung wrote:

Your would just retrieve the cart object and destroy it.

Fred

Ya, that's what. As the details inserted into that "carts" table aren't necessarily the ones the customer would have done and its needed just till the time of session, I have made "carts" table thinking it will just hold the temporary values and whenever customer hits "Emtpy cart" button, I wanted all the details related with that session deleted from this "carts" table as well. And after finalising the details and the payment is done then only the details from here be stored in corresponding tables permanently. If my logic is right can you please suggest me any better.. thanks..

I'm not sure what the stumbling point is here. carts are objects in the db, you have the ids of those objects in the session, what more do you need to destroy them ?

Fred

Frederick Cheung wrote:

Frederick Cheung wrote: > Fred

Sorry for the silly questions, so will I save carts id in the session. Can this work?

@cart=Cart.new(params[:cart])

this won't work, because you haven't saved the cart object (so it has no id)

session[:cart]=@cart.id

and later how can I retrieve id from the session?

The same as retrieving any other value from the sesion (ie session[:cart])

Fred

Frederick Cheung wrote:

On Oct 10, 11:46�am, Jay Pangmi <rails-mailing-list@andreas-s.net>

The same as retrieving any other value from the sesion (ie session[:cart])

Fred

Actually, params[:cart] is derived from <%form_for :cart ...%> Inside this, there are textfields corresponding to "carts" table and hence I could save the values in the form and I'm doing this way:

CONTROLLER: def add_to_cart     @cart_items=     @cart=find_cart(params[:cart])     if @cart.save       @cart_items << @cart     else       flash[:notice]="Details couldn't be saved"     end end

private

  def find_cart(cartobj)     session[:cart] ||= Cart.new(cartobj)   end

I'm using @cart_items array just because I couldn't iterate through the @cart to list all the entered details in the add_to_cart.rhtml as:

VIEW: <h1>Your details:</h1> <ul>   <%for item in @cart_items%>     <li><%=item.campsite%></li>     <li><%=item.arrival_date%></li>     <li><%=item.nights%></li>     <li><%=item.parents%></li>     <li><%=item.children%></li>     <li><%=item.family_claim%></li>   <%end%> </ul> <%=button_to "Empty cart", :action => :empty_cart%>

So, now when I click the "add to cart" button in the view everything gets added to the "carts" table and I'm taken to add_to_cart.rhtml with the list of details. Now in this case how can i empty it when empty_cart action is triggered for this specific session?

thanks fred.

Frederick Cheung wrote:

On Oct 10, 11:46�am, Jay Pangmi <rails-mailing-list@andreas-s.net>

The same as retrieving any other value from the sesion (ie session[:cart])

Fred

Actually, params[:cart] is derived from <%form_for :cart ...%> Inside this, there are textfields corresponding to "carts" table and hence I could save the values in the form and I'm doing this way:

CONTROLLER: def add_to_cart    @cart_items=    @cart=find_cart(params[:cart])    if @cart.save      @cart_items << @cart    else      flash[:notice]="Details couldn't be saved"    end end

private

def find_cart(cartobj)    session[:cart] ||= Cart.new(cartobj) end

I'm using @cart_items array just because I couldn't iterate through
the @cart to list all the entered details in the add_to_cart.rhtml as:

This doesn't seem to make any sense. For example the @cart_items array
will only ever contain 1 item, you are storing the whole cart object
in the session (what's the point of storing it in the database and the
session ?)

VIEW: <h1>Your details:</h1> <ul> <%for item in @cart_items%>    <li><%=item.campsite%></li>    <li><%=item.arrival_date%></li>    <li><%=item.nights%></li>    <li><%=item.parents%></li>    <li><%=item.children%></li>    <li><%=item.family_claim%></li> <%end%> </ul> <%=button_to "Empty cart", :action => :empty_cart%>

So, now when I click the "add to cart" button in the view everything gets added to the "carts" table and I'm taken to add_to_cart.rhtml
with the list of details. Now in this case how can i empty it when
empty_cart action is triggered for this specific session?

Actually if you check your code you'll find that beyond the first time
you call add_to_cart it won't actually do anything.

Is you cart object actually an item in a cart (rather than the
container, as the name usually implies) ?

Fred

Frederick Cheung wrote:

This doesn't seem to make any sense. For example the @cart_items array will only ever contain 1 item, you are storing the whole cart object in the session (what's the point of storing it in the database and the session ?)

session[:cart]=Cart.new(cartobj), what is this doing actually I'm not sure? As you said just to store carts id in the session, how can I do that? and while emptying the cart how can I get all the carts' id stored in the session and delete the records with that id from the carts table? With my current way, how can I validate individual details coz currently its all coming as params[:cart] coz first I have to validate and if alright save in the database.

Actually if you check your code you'll find that beyond the first time you call add_to_cart it won't actually do anything.

can you please show me how? I'm not yet familiar with rails code.

Is you cart object actually an item in a cart (rather than the container, as the name usually implies) ?

My cart object (params[:cart]) is all the values passed from the browser by the customer like date, time etc and this values I'm saving to the database table. Hope this is what you trying to know.

Thanks fred..

Frederick Cheung wrote: > This doesn't seem to make any sense. For example the @cart_items array > will only ever contain 1 item, you are storing the whole cart object > in the session (what's the point of storing it in the database and the > session ?)

session[:cart]=Cart.new(cartobj), what is this doing actually I'm not sure?

Your code actually says session[:cart] ||= Cart.new(cartobj)

what this does is: - if session[:cart] is set, do nothing - if not create a new instance of cart and store it in the session.

As you said just to store carts id in the session, how can I do that? and while emptying the cart how can I get all the carts' id stored in the session and delete the records with that id from the carts table? With my current way, how can I validate individual details coz currently its all coming as params[:cart] coz first I have to validate and if alright save in the database.

You would do something like like cart = Cart.create(...) session[:cart_id] = cart.id

When you need to access the cart later you would do cart = Cart.find session[:cart_id] and then do stuff with the instance of cart (eg destroy it)

> Actually if you check your code you'll find that beyond the first time > you call add_to_cart it won't actually do anything.

can you please show me how? I'm not yet familiar with rails code.

> Is you cart object actually an item in a cart (rather than the > container, as the name usually implies) ?

My cart object (params[:cart]) is all the values passed from the browser by the customer like date, time etc and this values I'm saving to the database table. Hope this is what you trying to know.

That's not what I was asking. Some of what you were saying was implying that a customer would have multiple carts at the same time, whereas normally a person only ever has one cart (possibly containing more than one thing). In that case you may not want to be persisting the cart but the items in the cart (which might be what you're trying to do already, but calling them carts just makes everything rather confused).

Fred

Thanks Fred for your detailed answer. Now, I realize where I stand. About the "carts" table I'm assuming that at a particular time more than one customer will be shopping so this "carts" table will hold items of each customer with a reference to a session id given to each customer. Each details for each customer will be retrieved and deleted with the help of this session info. Anyway, now I think I can reach somewhere.. thnx very much.

Sorry, I'm back again as I couldn't go much far than I thought.. I did the following:

def add_to_cart cart=Cart.create(......) session[:cart_id] = cart.id @items=Cart.find(session[:cart_id]) end

Now, session[:cart_id]=cart.id is only storing the id of the newly added cart item so, Cart.find(session[:cart_id]) is only giving me one row. Hence, despite the fact that a customer has added multiple items in the cart, I could only show the latest item added in the cart to the customer. So, thought of using this:

@cart_ids = session[:cart_id] = cart.id @cart_ids << session[:cart_id]

but couldn't think of the way to iterate through each id in the @cart_ids and show the result in the add_to_cart.rhtml. Any better suggestion or solution for this??? thanks..

Sorry, I'm back again as I couldn't go much far than I thought.. I did the following:

def add_to_cart cart=Cart.create(......) session[:cart_id] = cart.id @items=Cart.find(session[:cart_id]) end

Now, session[:cart_id]=cart.id is only storing the id of the newly added cart item so, Cart.find(session[:cart_id]) is only giving me one row. Hence, despite the fact that a customer has added multiple items in the cart, I could only show the latest item added in the cart to the customer. So, thought of using this:

@cart_ids = session[:cart_id] = cart.id @cart_ids << session[:cart_id]

How could that ever work? That instance variable doesn't survive across requests. You would need something like

cart=Cart.create(......) session[:cart_ids] ||= session[:cart_ids] << cart.id

You can then later use Cart.find(session[:cart_ids]) to get all those cart objects back.

Fred

Frederick Cheung wrote:

Ok, Now as I've made session[:cart_ids] and array with:

session[:cart_ids] ||=

how can I clear all the stored ids in the session coz 'session[:cart_ids] = nil' isn't working. Also as I have ids in the array referenced by session[:cart_ids] and that the carts table only stored the camp location, to get the id of each camp location stored in the cart, I'm doing:

@cart=Cart.find(session[:cart_ids])

for item in @cart @camp_id=Campsite.find(:all, :conditions => ['camp_location = ?',item.campsite]) Booking.create(......,:camp_id => @camp_id.id) end

But, it doesn't seem to work. Any better way? plz suggest me.. thanks.

Jay Pangmi wrote:

Ok, Now as I've made session[:cart_ids] and array with:

session[:cart_ids] ||=

how can I clear all the stored ids in the session coz 'session[:cart_ids] = nil' isn't working. Also as I have ids in the array referenced by session[:cart_ids] and that the carts table only stored the camp location, to get the id of each camp location stored in the cart, I'm doing:

@cart=Cart.find(session[:cart_ids])

for item in @cart @camp_id=Campsite.find(:all, :conditions => ['camp_location = ?',item.campsite]) Booking.create(......,:camp_id => @camp_id.id) end

But, it doesn't seem to work. Any better way? plz suggest me.. thanks.

session[:cart_ids].clear gives error as well instead. In case of the for loop the when done as: