views:

28

answers:

2

Suppose this is my users controller:-

class UsersController < ApplicationController
 def show
  @user = session[:user]
 end

 def prepare
  session[:user]= User.find(:first)
  redirect_to :action => 'show'
end

def update
 @user = session[:user]
 @user.name = 'rai'
redirect_to :action => 'show'
end
end

View for show.html.erb

<%= @user.name %>
Show page
<%= link_to 'Update', :action=> 'update' %>

Now Explaining the issue:--- Suppose first time user opens the browser with

 http://localhost:3000/users/prepare

o/p will be:---

 Mohit Show page Update  // supposing user table has values mohit as name

Now when he click on update he will get as output like this:--

  rai Show page Update

But this should not happen cause

firstly when are at prepare action where value is fecthced from db and its mohit. and then he is redirected to show ie displying the values from session. ie mohit

Now when user click on the update he is redirected to update when value from session is stored to a user instance and the name attribute of that user instance has been modified to rai. and finally redirected to show page.

Now in this page when user's name is displayed its showing rai.. thats the QUESTION why?? cause session should store the same mohit value cause we havnt made any change in session..

+2  A: 

When you are doing

@user = session[:user]

@user variabe is assigned reference to the object session[:user], not the copy of it. So when you are modifying @user, session[:user] is also modified, as they are essentially the same object.

Voyta
Ya thats whats happening.. i can understand but i am not able to understand why this is happening..!!!
piemesons
In ruby variables hold references, not values. So when you are assigning, you are copying references. http://ruby-doc.org/docs/Newcomers/ruby.html#objects
Voyta
A: 

I'm not sure, but I think it is something with hashes and classes and about copying them. So when you do:

@user = session[:user]

You are not making a copy of object but it is something likre reference in C++, both @user and session[:user] are reffering to the same object, so when you modify one, you get both modified.

Example from console:

a = {}
a[:user] = User.first
a[:user].firstname           # => "Mohit"
b = a[:user]
b.firstname = 'rai'
a[:user].firstname           # => 'rai'
a[:user] = User.first
a[:user].firstname           # => 'Mohit'
klew
Ya thats whats happening.. i can understand but i am not able to understand why this is happening..!!!
piemesons
@piemesons: when you assign `@user = session[:user]` you are not copying user object. You are copying 'pointer' to that object. So on example, if you have a friend called "Bob" and you give him 100 $, then he has 100$ :). Now, if you call him "Foo" (it is the same person, but different name) and you give him another 100$, he has now 200$, not 100$. It is very similar with what happend with your session object.
klew
In this console example, you can call `a[:user].object_id` and `b.object_id` and it is the same. It means that both `a[:user]` and `b` refers to the same object.
klew