I'm looking for a mechanism by which to facilitate user preferences. I also want to have a set of "master" prefs that are used if the currently logged in user doesn't have a specific pref set. I see several questions similar to this, but they seem to get into theory instead of simply proposing a quality solution.
Basically I'm looking for input on management as well as storage -- models, controllers, etc. Initially I was considering simply going with a normalized table of 50+ columns (for performance etc.). However, I plan on adding various, unknown preferences in the future and, performance aside, I could imagine multiple columns getting out of hand. Thoughts?
In my mind, the best way to define and use defaults is to add another row in the user preferences table, and load it as a class variable in your model. Then override the accessors to find the defaults if the preference hasn't been found. Something like this:
class UserPreference < ActiveRecord::Base
# load default preferences as a class variable
@@defaults ||= find(1).attributes
# redefine accessors or each column to load default if nil
column_names.each do |column|
method_name = "#{column}_with_default".to_sym
send :define_method, method_name do
value = send("#{column_without_default}")
case value
when nil
@@defaults[column]
else
value
end
end
alias_method_chain column, :default
end
...
end
Essentially the default preferences (loaded from row 1) are stored in the Model as a class variable. All the accessors are redefined and made part of an alias method chain so that the default would be returned if the returned value was nil. I wanted to use || instead of case, but that would cause problems in the event that the user had set a boolean preference to false.
Edit: N.B. I don't know of a good way to update the defaults in a rails app without restarting the server.