Session mgmt. bug - ActiveRecord & MemoryStore session store


#1

Windows XP Pro
Rails 1.1.2

I need some help verifying this behavior that I’m seeing.

BUG: Objects in session which are descendants of ActiveRecord::Base lose
attributes on subsequent requests when using CGI::Session::MemoryStore.

TO REPRODUCE:

  1. Set up MemoryStore as the session database manager in the appropriate
    environment.rb file in config
  2. Create a model object X that descends from ActiveRecord::Base
  3. Add an attr_accessor for an attribute test_attr to model object X
  4. Create one action in your controller that
    creates a new X
    sets the test_attr value on X to be something
    stores X in the session
  5. Create another action in your controller that simply attempts to
    access the test_attr attribute on the session copy of X

Assuming that you have X as a descendant of ActiveRecord::Base somewhere
(you could just use an existing object and add an attr_accessor to it,
of course), here’s what you would put in the controller:

Model code:

class X < ActiveRecord::Base
attr_accessor :test_attr
end

Controller code:

public
def test_action
test_object = X.new
session[:test_object] = test_object
session[:test_object].test_attr = 5
render(:action => ‘index’)
end

public
def test_action2
puts “Value is: #{session[:test_object].test_attr}”
render(:action => ‘index’)
end

View code in index.rhtml to invoke these actions:

<%= link_to(“Test action”, :controller => ‘yourcontroller’, :action =>
‘test_action’) %>

<%= link_to(“Test action 2”, :controller => ‘yourcontroller’, :action =>
‘test_action2’) %>

You will get an exception like: undefined method `test_attr’ for
#<X:0x39e0270>

If you comment out the use of MemoryStore as the session database
manager, your code should work. Simply toggling the MemoryStore setting
will cause this code to fail or not fail, as the case may be.

It seems that when the session is “reconstituted” back from the
MemoryStore, something happens to the magic that allows the session copy
of the object to know about it’s attributes?

NOTE: Using the “model :x” directive in the controller does not help.
NOTE: A model object that is NOT a descendant of ActiveRecord::Base will
work fine.

If this is actually a bug, how do I report it?

Wes


#2

Additional info.:

  1. Just to be clear, the bug is that the attribute is not accessible via

session[:test_object].test_attr

on the next request (in the test case, test_action2).

  1. Also, the use of an attr_accessor type attribute was for the test
    case. In my real life problem that led me to discover this, it occurs
    on an attribute that is related to the object via a “has_many”
    relationship. Using the same test methods and attempting to set this
    attribute on the object in one request and then trying to retrieve it in
    a second request also fails when the session is being managed using
    MemoryStore.

Wes

Wes G. wrote:

Windows XP Pro
Rails 1.1.2

I need some help verifying this behavior that I’m seeing.

BUG: Objects in session which are descendants of ActiveRecord::Base lose
attributes on subsequent requests when using CGI::Session::MemoryStore.

TO REPRODUCE:

  1. Set up MemoryStore as the session database manager in the appropriate
    environment.rb file in config
  2. Create a model object X that descends from ActiveRecord::Base
  3. Add an attr_accessor for an attribute test_attr to model object X
  4. Create one action in your controller that
    creates a new X
    sets the test_attr value on X to be something
    stores X in the session
  5. Create another action in your controller that simply attempts to
    access the test_attr attribute on the session copy of X

Assuming that you have X as a descendant of ActiveRecord::Base somewhere
(you could just use an existing object and add an attr_accessor to it,
of course), here’s what you would put in the controller:

Model code:

class X < ActiveRecord::Base
attr_accessor :test_attr
end

Controller code:

public
def test_action
test_object = X.new
session[:test_object] = test_object
session[:test_object].test_attr = 5
render(:action => ‘index’)
end

public
def test_action2
puts “Value is: #{session[:test_object].test_attr}”
render(:action => ‘index’)
end

View code in index.rhtml to invoke these actions:

<%= link_to(“Test action”, :controller => ‘yourcontroller’, :action =>
‘test_action’) %>

<%= link_to(“Test action 2”, :controller => ‘yourcontroller’, :action =>
‘test_action2’) %>

You will get an exception like: undefined method `test_attr’ for
#<X:0x39e0270>

If you comment out the use of MemoryStore as the session database
manager, your code should work. Simply toggling the MemoryStore setting
will cause this code to fail or not fail, as the case may be.

It seems that when the session is “reconstituted” back from the
MemoryStore, something happens to the magic that allows the session copy
of the object to know about it’s attributes?

NOTE: Using the “model :x” directive in the controller does not help.
NOTE: A model object that is NOT a descendant of ActiveRecord::Base will
work fine.

If this is actually a bug, how do I report it?

Wes