Session question

Hi, I’m reading Agile Web D. 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:

def add_product(product)
@items << product
end

where @items is an array and product is created with:

def add_to_cart
@cart=find_cart
product=Product.find(params[:id])
@cart.add_product(product)
end

and there is a use of find_cart method which is used to find cart or
create new if there isn’t any as:

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

Now, I’m trying to follow the author but my situation is littly twisted
as in my case customer will enter lots other details than just a
campsite name. For eg: it will be campsite name, arrival_date, days to
stay, group size and also claims for family rate if eligible. So, I’ve
thought of saving all these details in the “carts” table in the
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

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:

def empty_cart
session[:cart]=nil
redirect_to :action => :index
end

If i do the same just the data in the sessions table is being deleted
and the details in the carts table are still there. So, how can I delete
details related with the particular session from this ‘carts’ table as
it will contain details from other users as well with different session
id. Thanks for your time to go thru and please advice any
suggestions… thnx

On Oct 10, 9:07 am, Jay P. [email protected]
wrote:

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 C. 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…

On 10 Oct 2008, at 10:35, Jay P. wrote:

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 C. wrote:

On 10 Oct 2008, at 10:35, Jay P. wrote:
Fred

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

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

session[:cart][email protected]

and later how can I retrieve id from the session?

thanks Fred.

On Oct 10, 11:46 am, Jay P. [email protected]
wrote:

Frederick C. wrote:

On 10 Oct 2008, at 10:35, Jay P. 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][email protected]

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 C. wrote:

On Oct 10, 11:46�am, Jay P. [email protected]

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:

Your details:

    <%for item in @cart_items%>
  • <%=item.campsite%>
  • <%=item.arrival_date%>
  • <%=item.nights%>
  • <%=item.parents%>
  • <%=item.children%>
  • <%=item.family_claim%>
  • <%end%>
<%=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 C. 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…

On Oct 10, 2:56 pm, Jay P. [email protected]
wrote:

Frederick C. 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)

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.

On 10 Oct 2008, at 12:13, Jay P. wrote:

this, there are textfields corresponding to “carts” table and hence I
end
@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 ?)

<%end%>

<%=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

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…

On Oct 11, 7:54 am, Jay P. [email protected]
wrote:

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 C. wrote:

On Oct 11, 7:54�am, Jay P. [email protected]
wrote:

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

Thanks Fred I owe you fortune…

Jay

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 P. 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:

@camp_id = Campsite.find(:all, :select => ‘id’, :conditions =>
[‘camp_location = ?’,item.campsite])
Booking.create(…,:camp_id => @camp_id)

No matter which campsite I select, 1 is saved as an id in camp_id column
in bookings table… plz any suggestion?? thanks
I