UserPreferences
An ActiveRecord backed user preference library that supports:
- Categories (currently non-optional)
- Binary and non-binary preferences
- Default values
- Value validation
- Retrieving users scoped by a particular preference
Installation
Add this line to your application's Gemfile:
gem 'user_preferences'
And then execute:
$ bundle
Run the installation script:
$ rails g user_preferences:install
This will copy across the migration and add an empty preference definition file in config/
Finally, run the database migrations:
$ rake db:migrate
Defining preferences
Your preferences are defined in config/user_preferences.yml. You define each of your
preferences within a category. This example definition for a binary preference implies that users receive emails notifications by default but not newsletters:
emails:
notifications: true
newsletters: false
You can configure non-binary preferences. For example, if users could choose periodical notification digests, the configuration might look like this:
emails:
notifications:
default: instant
values:
- off
- instant
- daily
- weekly
newsletters: false
You can add as many categories as you like:
emails:
notifications: true
newsletters: false
beta_features:
two_factor_authentication: false
the_big_red_button: false
API
set
Similar to ActiveRecord, setting a preference returns true or false depending on whether or not it was successfully persisted:
user.preferences(:emails).set(notifications: 'instant') # => true
user.preferences(:emails).set(notifications: 'some_typo') # => false
You can set multiple preferences at once:
user.preferences(:emails).set(notifications: 'instant', newsletter: true) # => true
get
A single preference:
user.preferences(:emails).get(:notifications) # => 'instant'
all
All preferences for a category:
user.preferences(:emails).all # => { notifications: 'instant', newsletter: true }
reload
Reload the preferences from the database; since something else might have changed the user's state.
user.preferences(:emails).reload # => { notifications: 'instant', newsletter: true }
Scoping users
= User.with_preference(:email, :newsletter, true) #=> an ActiveRecord::Relation
Note: this will include users who have not overriden the default value if the value incidentally matches the default value.
Other useful stuff
Single preference definition
- Get your preference definition (as per your .yml) as a hash:
UserPreferences.definitions - Get the definition for a single preference:
ruby preference = UserPreferences[:emails, :notifications] preference.default # => 'instant' preference.binary? # => false preference.permitted_values # => ['off', 'instant', 'daily', 'weekly'] - Retrieve the default preference state with
UserPreferences.defaults. You can also scope to a category:UserPreferences.defaults(:emails)
Testing
$ rake test
Contributing
- Fork it ( http://github.com/mubi/user_preferences/fork )
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create new Pull Request