paulodeon-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org
2008-May-21 11:27 UTC
Replacing ActiveRecordStore::Session with a custom model
Has anyone managed to replace ActiveRecordStore::Session with their own model? In the source (http://dev.rubyonrails.org/browser/trunk/actionpack/lib/ action_controller/session/active_record_store.rb) it says you can override the default by setting CGI::Session::ActiveRecordStore.session_class = MySessionClass I have tried doing this in a number of ways but I get all kinds of weird errors, as varied as the methods I''ve tried. Before you shoot me down for trying to do something I shouldn''t let me explain why I want to do this. I''d like a session model that looks something like: class Session < ActiveRecord::Base has_many :product_viewings, :dependent => :destroy has_many :products, :through => :product_viewings, :limit => 10, :include => :image belongs_to :order belongs_to :user end In my controller I would like to do something like session.model.user = @user and @recently_viewed_products = session.model.products Because I cannot replace ActiveRecordStore::Session with my session class above I have to do instead: session.model.user_id = @user.id and @recently_viewed_products Session.find_by_session_id(session.session_id).products I don''t think it''s unreasonable to want to treat session.model as a first class ActiveRecord model, anything else just seems a bit half- baked. Any ideas on how I could make this happen would be greatly appreciated. Paul Odeon --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
paulodeon-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org
2008-May-21 23:18 UTC
Re: Replacing ActiveRecordStore::Session with a custom model
Ok I finally nailed it... I found that using CGI::Session::ActiveRecordStore.session_class Session worked in production mode but not in dev, I could also make it work in dev but only by setting config.cache_classes = true In dev it would work on the first page load but crash with a stack too deep error on the second and subsequent attempt. Definitely a dependencies issue then... All the classes are reloaded on every request, including our custom Session class. However, CGI::Session::ActiveRecordStore.session_class is only set on application initialization, and the session_class variable is left holding a stale version of the Session class. What we need is a way to update ActiveRecordStore with a fresh Session class after every request, the magic line of code to do that is at the end of this post. So to create your own session model with all the ActiveRecord goodness follow these steps: 1. config/initializers/session.rb CGI::Session::ActiveRecordStore.session_class = Session 2. app/models/session.rb class Session < CGI::Session::ActiveRecordStore::Session has_many :product_viewings, :dependent => :destroy has_many :products, :through => :product_viewings, :limit => 10, :include => :image #Or whatever ActiveRecord stuff you like end 3. config/environment.rb Rails::Initializer.run do |config| config.action_controller.session_store = :active_record_store config.to_prepare { CGI::Session::ActiveRecordStore.session_class Session if ENV[''RAILS_ENV''] == ''development'' } # This is the one end config.to_prepare executes the block it is passed before each request in rails. In it, we pass the freshly reloaded class to the Session store but only in dev. I hope this helps someone struggling with the same problem... Cheers On May 21, 12:27 pm, "paulod...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org" <paulod...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> Has anyone managed to replace ActiveRecordStore::Session with their > own model? > > In the source (http://dev.rubyonrails.org/browser/trunk/actionpack/lib/ > action_controller/session/active_record_store.rb) it says you can > override the default by setting > CGI::Session::ActiveRecordStore.session_class = MySessionClass > > I have tried doing this in a number of ways but I get all kinds of > weird errors, as varied as the methods I''ve tried. > > Before you shoot me down for trying to do something I shouldn''t let me > explain why I want to do this. > > I''d like a session model that looks something like: > > class Session < ActiveRecord::Base > has_many :product_viewings, :dependent => :destroy > has_many :products, :through => :product_viewings, :limit => > 10, :include => :image > > belongs_to :order > belongs_to :user > end > > In my controller I would like to do something like > > session.model.user = @user > > and > > @recently_viewed_products = session.model.products > > Because I cannot replace ActiveRecordStore::Session with my session > class above I have to do instead: > > session.model.user_id = @user.id > > and > > @recently_viewed_products > Session.find_by_session_id(session.session_id).products > > I don''t think it''s unreasonable to want to treat session.model as a > first class ActiveRecord model, anything else just seems a bit half- > baked. > > Any ideas on how I could make this happen would be greatly > appreciated. > > Paul Odeon--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
paulodeon-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org
2008-May-22 15:50 UTC
Re: Replacing ActiveRecordStore::Session with a custom model
One small glitch with the above solution Any of the script/* and rake scripts seem to fail with some sort of dependency error This is a bug (http://dev.rubyonrails.org/ticket/10520) and is apparently fixed in 2.0.2, although that''s what I am using and I still get the error. As described in the link above, I put the following above the config.to_prepare block and everything worked perfectly. #fixes rails bug described here: http://dev.rubyonrails.org/ticket/10520 #this monkey patch should be removed when problem is fixed in rails module Rails class Configuration def to_prepare(&callback) after_initialize do require ''dispatcher'' unless defined?(::Dispatcher) Dispatcher.to_prepare(&callback) end end end end On May 22, 12:18 am, "paulod...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org" <paulod...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> Ok I finally nailed it... > > I found that using CGI::Session::ActiveRecordStore.session_class > Session worked in production mode but not in dev, I could also make it > work in dev but only by setting config.cache_classes = true > > In dev it would work on the first page load but crash with a stack too > deep error on the second and subsequent attempt. > > Definitely a dependencies issue then... > > All the classes are reloaded on every request, including our custom > Session class. However, CGI::Session::ActiveRecordStore.session_class > is only set on application initialization, and the session_class > variable is left holding a stale version of the Session class. What we > need is a way to update ActiveRecordStore with a fresh Session class > after every request, the magic line of code to do that is at the end > of this post. > > So to create your own session model with all the ActiveRecord goodness > follow these steps: > > 1. config/initializers/session.rb > CGI::Session::ActiveRecordStore.session_class = Session > > 2. app/models/session.rb > class Session < CGI::Session::ActiveRecordStore::Session > has_many :product_viewings, :dependent => :destroy > has_many :products, :through => :product_viewings, :limit => > 10, :include => :image > #Or whatever ActiveRecord stuff you like > end > > 3. config/environment.rb > Rails::Initializer.run do |config| > config.action_controller.session_store = :active_record_store > config.to_prepare { CGI::Session::ActiveRecordStore.session_class > Session if ENV[''RAILS_ENV''] == ''development'' } # This is the one > end > > config.to_prepare executes the block it is passed before each request > in rails. In it, we pass the freshly reloaded class to the Session > store but only in dev. > > I hope this helps someone struggling with the same problem... > > Cheers > > On May 21, 12:27 pm, "paulod...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org" > > <paulod...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote: > > Has anyone managed to replace ActiveRecordStore::Session with their > > own model? > > > In the source (http://dev.rubyonrails.org/browser/trunk/actionpack/lib/ > > action_controller/session/active_record_store.rb) it says you can > > override the default by setting > > CGI::Session::ActiveRecordStore.session_class = MySessionClass > > > I have tried doing this in a number of ways but I get all kinds of > > weird errors, as varied as the methods I''ve tried. > > > Before you shoot me down for trying to do something I shouldn''t let me > > explain why I want to do this. > > > I''d like a session model that looks something like: > > > class Session < ActiveRecord::Base > > has_many :product_viewings, :dependent => :destroy > > has_many :products, :through => :product_viewings, :limit => > > 10, :include => :image > > > belongs_to :order > > belongs_to :user > > end > > > In my controller I would like to do something like > > > session.model.user = @user > > > and > > > @recently_viewed_products = session.model.products > > > Because I cannot replace ActiveRecordStore::Session with my session > > class above I have to do instead: > > > session.model.user_id = @user.id > > > and > > > @recently_viewed_products > > Session.find_by_session_id(session.session_id).products > > > I don''t think it''s unreasonable to want to treat session.model as a > > first class ActiveRecord model, anything else just seems a bit half- > > baked. > > > Any ideas on how I could make this happen would be greatly > > appreciated. > > > Paul Odeon--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---