Wes Gamble
2006-May-09 16:35 UTC
[Rails] Session mgmt. bug - ActiveRecord & MemoryStore session store
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: 0) Set up MemoryStore as the session database manager in the appropriate environment.rb file in config 1) Create a model object X that descends from ActiveRecord::Base 2) Add an attr_accessor for an attribute test_attr to model object X 3) 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 4) 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 -- Posted via http://www.ruby-forum.com/.
Wes Gamble
2006-May-09 17:18 UTC
[Rails] Re: Session mgmt. bug - ActiveRecord & MemoryStore session s
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). 2) 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 Gamble 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: > > 0) Set up MemoryStore as the session database manager in the appropriate > environment.rb file in config > 1) Create a model object X that descends from ActiveRecord::Base > 2) Add an attr_accessor for an attribute test_attr to model object X > 3) 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 > 4) 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-- Posted via http://www.ruby-forum.com/.