Forum: Ruby on Rails Session mgmt. bug - ActiveRecord & MemoryStore session store

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Bb4bdf2b184027bc38d4fb529770cde5?d=identicon&s=25 Wes Gamble (weyus)
on 2006-05-09 18:34
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
Bb4bdf2b184027bc38d4fb529770cde5?d=identicon&s=25 Wes Gamble (weyus)
on 2006-05-09 19:18
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
This topic is locked and can not be replied to.