0.01
No release in over 3 years
Low commit activity in last 3 years
user_preference is a small library for setting and getting categorized user preferences. Supports both binary and multivalue preferences and default values.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.7
~> 12.3.3
~> 3.9.0

Runtime

 Project Readme

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

Add preferences to your model

Assuming you have a model called User, you can associate it with preferences as follows:

class User < ActiveRecord::Base

  has_preferences

  # the rest of your code ...
end

This declaration takes no arguments, and simply sets up the correct associations along with making available the rest of the methods described in the API section below.

Defining preferences

Your preferences, along with their default values, 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

Binary preferences can be enhanced to support multiple values while maintaining backwards compatibility on the API side:

emails:
  notifications:
    default: true
    acts_as_binary: true
    values:
      - false
      - true
      - email
      - push

This will support setting the preference using integers, booleans, and strings for the first 2 values.

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

  newsletter_users = User.with_preference(:email, :newsletter, true) #=> an ActiveRecord::Relation

Note: this will include users who have not overridden 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:
  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

  1. Fork it ( http://github.com/mubi/user_preferences/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request