I want to handle two kinds of global configuration settings:
What's the best way to store these settings? Database, configuration file, hardcoded in the source, ...?
For both cases database. You're going to be using the same structures for multiple people/products so it makes sense. Also it allows you to change things without restarting the server.
I've handled it this way in the past: For settings specific to the user, I've created a UserSettings model/table, that has a one-to-one to relationship with a user. The reasoning for this is that the majority of my operations involving users do no not require these settings to be loaded, so they're only included on user loads from the database when I need them.
When I do this, I'll usually group my column names, so that I can write helpers that dynamically create based on the names. Meaning that I won't have to modify my views to incorporate new settings unless I add one with a different naming scheme.
For the settings specific to a product, well that depends on how you are doing things. And there are a couple of ways to interpret your question.
The way I read it is that you want to decide on a product level. What settings users can overriding or disabling a user's setting. And possibly define some product specific settings.
I would use a one-to-many product to setting relationship. The setting table would be something simplistic (product_id, setting_name, setting_default_value, allow_user_change)
This does a number of things. It lets you have a variable list of settings for different products (Perfect for the case where you're offering many different products instead of varying tiers of access to services). It also lets you define what settings a user can/can't change and give values for that product type. That can be changed from an administrator view without restarting the application. It's also not tied to user settings, to the point where if a user doesn't have a setting listed in the product_settings there will be no problems.
The downside is you will have multiple common settings in this table. I would move settings that every product will have a different value to a field in the product table.
You will also have to write validations to ensure that a user does not change a setting their product says they can't. You will also have to write helper methods to merge settings from the product and user sides.
class Flag < ActiveRecord::Base
# id, user_id, name, value (serialized probably)
belongs_to :user
DEFAULTS = {
"newsletter" => false
}
def self.lookup(user, flag)
# Please involve memcached here
case flag
when "ssl_enabled"
# Check if user has paid for sufficient access to SSL
return false
else
stored_flag = self.find_by_user_id_and_name(user.id, flag)
if stored_flag
return stored_flag.value
else
return DEFAULTS[flag]
end
end
end
end
class User < ActiveRecord::Base
has_many :flags
def flag(name)
return Flag.lookup(self, name)
end
end
For stuff that's product edition based, you probably can't really store things in the database, because the flag is going to be based on some piece of authorization code, rather than static data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With