Duane Johnson
2005-Jan-15 02:26 UTC
Storing temporary defaults in the session under the controller''s namespace
I made a handy feature for those who need persistent "settings" or defaults at the session level--this snippet of code was useful to me when I had a list view that had options such as "sort by" and "show only this category". When the user re-visits the list view after having visited an arbitrary number of other pages, I wanted the view to stay the way the user had it when they left it. As a result, the following code separates these little "defaults" in the session in to controller namespaces and stores the values in the session. For example: store_default :category_id, @params[''category_id''].to_i results in @session[''MerchandiseController''][''category_id''] = @params[''category_id''].to_i which is later automagically retrieved by load_defaults as @category_id in the MerchandiseController class. Duane CODE SNIPPETS: Usage: in MerchandiseController I have the following: class MerchandiseController < ApplicationController before_filter :load_defaults def list # First thing, load any saved defaults, or set them if called to do so # (If the user hits the ''reload'' button, defaults are saved.) if (@params[''reload'']) store_default :category_id, @params[''category_id''].to_i store_default :order_by, @params[''order_by''] end ... end end And in application.rb: # Given a symbol (key), store the value in both an instance # variable AND the session so that it can be loaded again at # some arbitrary time later on (for example, when the user # re-visits a certain page, and you want the same information # to be displayed). # Example (assuming the call is made from MerchandiseController): # store_default :order_by, "name" # => "name" # (side effect: store "name" in @order_by and # @session[''MerchandiseController''][''order_by'']) def store_default(key, value) className = self.class.to_s keyName = key.id2name # Make sure there''s a namespace for this class''s defaults @session[className] ||= Hash.new # Store the key/value in the session @session[className][keyName] = value # Store the key/value as an instance variable if (value.is_a? String) eval "@#{keyName} = ''#{value}''" else eval "@#{keyName} = #{value}" end end # Given a symbol, load its string-equivalent from the session # and store it in an instance variable. For example, if the # method is called from within the class "MerchandiseController" # as "load_default :category_id" then this method will retrieve # @session[''MerchandiseController''][''category_id''] and store it # in @category_id. def load_default(key) begin value = @session[self.class.to_s][key.id2name] if (value.is_a? String) eval "@#{key.id2name} = ''#{value}''" else eval "@#{key.id2name} = #{value}" end rescue nil end end # Load all of the values stored in the session (only the # ones stored for this class) and create instance variables # for each. So for example, if @session[''MerchandiseController''] # contains the Hash { ''category_id'' => 1, ''order_by'' => ''name'' }, # then load_defaults will make @category_id = 1 and # @order_by = ''name''. def load_defaults return if @session[self.class.to_s] == nil @session[self.class.to_s].each do |key,value| if (value.is_a? String) eval "@#{key} = ''#{value}''" else eval "@#{key} = #{value}" end end end