AWDWR Depot App / Ruby question

Yes I’m one of those folks learning ruby by way of Rails … I’m confounded by the cart …

I understand this

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

Then called as

@cart = find_cart

What I don’t understand is what’s actually returned here …

I keep expecting to see:

session[:cart] = cart

Somewhere to save the cart to the session but I don’t see that anywhere.

Does the find_cart method return a reference to the session variable? Do all methods return references? …

Fluffy Hippo wrote:

Yes I'm one of those folks learning ruby by way of Rails ... I'm confounded
by the cart ...

I understand this

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

Then called as

@cart = find_cart

What I don't understand is what's actually returned here ...

I keep expecting to see:

session[:cart] = cart

Somewhere to save the cart to the session but I don't see that anywhere.

The ||= is what does the assignment of a new empty cart to the session if it doesn't already have a cart. Written out very verbosely that does:

if session[:cart]
   return session[:cart]
else
   session[:cart] = Cart.new
   return session[:cart]
end

The add_to_cart described later on is what adds individual items to the cart.

But I guess where I’m hung up on is is it returning the value of session[:cart], ie, a cart object with the value of the cart, or is it returning a reference to that actual session[:cart]?

I’m missing the magic of how the actions taken on the ‘cart’ are actually reflected in the session[:cart] persistent between calls.

Fluffy Hippo wrote:

But I guess where I'm hung up on is is it returning the *value* of
session[:cart], ie, a cart object with the value of the cart, or is it
returning a reference to that actual session[:cart]?

I'm missing the magic of how the actions taken on the 'cart' are actually
reflected in the session[:cart] persistent between calls.

The book talks briefly about sessions and how they are stored persistently in that section on carts or you can skip to the reference section and read more about them there.

session[:cart] returns whatever object is associated with that key, in this case a Cart object, sort of like this:

irb(main):015:0> a = { :id => 1, :name => "blah" }
=> {:name=>"blah", :id=>1}
irb(main):016:0> a[:name]
=> "blah"
irb(main):017:0> session = Hash.new
=> {}
irb(main):018:0> session[:cart] = a
=> {:name=>"blah", :id=>1}
irb(main):019:0> session[:cart]
=> {:name=>"blah", :id=>1}
irb(main):020:0> session[:cart].object_id
=> 23456251850360
irb(main):021:0> a.object_id
=> 23456251850360
irb(main):022:0> session.object_id
=> 23456251831800

The session contains a reference to the cart. Because Rails store away everything referenced from the session at the end of a request, any updates to the cart during that request will be saved.

Dave

Below, find_cart will return either the current cart object (session[:cart]) or if there isn't a current cart then a new one will be created, saved in session[:cart] and then returned. Later in AWDWR you can find empty_cart where session[:cart] is set to nil. I searched the PDF and surprisingly I don't see any instances where an updated cart is saved to the session, but I'd expect that in add_to_cart and would look like:

session[:cart] = @cart

Fluffy Hippo wrote:

Yes I'm one of those folks learning ruby by way of Rails ... I'm confounded by the cart ...

I understand this

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

Then called as

@cart = find_cart

What I don't understand is what's actually returned here ...

I keep expecting to see:

session[:cart] = cart

Somewhere to save the cart to the session but I don't see that anywhere.

Does the find_cart method return a reference to the session variable? Do all methods return references? ...

No, @cart is an instance of Cart. There does need to be a place to save an updated cart back into the session.

David

The session already has a reference to the cart set when the request comes in--there's no need to set it again unless you want to use a new cart object (which you don't...)

Dave

Ahhh! So there is ‘magic’ in the [] method of session that keeps references to returned items? Thus making this a rails thing, not a ruby thing … guess I’ll have to go dig around and find the session manager in the rails tree and see what it does; but it’s a little clearer now than it was. I was thinking it was a language (ruby) concept I wasn’t groking …

Hi, this is a builtin Rails session hash using the Ruby language.
Please remember that Ruby is a language and Rails is a framework.
Please read "Programminh Ruby" on using a Hash. Then reread the
section(s) on using session variables.

Good luck,

-Conrad

No, nothing magic:

hash = {}

cart = [ 1, 2, 3 ]

hash[:cart] = cart

cart[1] = ‘rabbit’

puts hash[:cart] #=> [ 1, ’ rabbit’, 3 ]

Yeah, I’ve just been doing some reading … my problem was much more fundemental. I didn’t get that everything is a reference in ruby,

Thanks to all. I think I ve got my head around this one now. I’m sure there will be more though;)

Dave Thomas wrote:

Ahhh! So there is 'magic' in the [] method of session that keeps references to returned items? Thus making this a rails thing, not a ruby thing ... guess I'll have to go dig around and find the session manager in the rails tree and see what it does; but it's a little clearer now than it was. I was thinking it was a language (ruby) concept I wasn't groking ...

No, nothing magic:

hash = {}
cart = [ 1, 2, 3 ]

hash[:cart] = cart

cart[1] = 'rabbit'

puts hash[:cart] #=> [ 1, ' rabbit', 3 ]

Also as I mentioned earlier the "magic" behind the session object is explained in detail in Dave's book which you are already using. There's no need to read the actual code if you are just trying to get a basic understanding of how it works.