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