Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Adds support for easily creating custom preferences for models
Fetching latest commit...
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


== preferences

+preferences+ adds support for easily creating custom preferences for models.

== Resources









== Description

Preferences for models within an application, such as for users, is a pretty
common idiom.  Although the rule of thumb is to keep the number of preferences
available to a minimum, sometimes it's necessary if you want users to be able to
disable things like e-mail notifications.

Generally, basic preferences can be accomplished through simple designs, such as
additional columns or a bit vector described and implemented by preference_fu[].
However, as you find the need for non-binary preferences and the number of
preferences becomes unmanageable as individual columns in the database, the next
step is often to create a separate "preferences" table.  This is where the +preferences+
plugin comes in.

+preferences+ encapsulates this design by hiding the fact that preferences are
stored in a separate table and making it dead-simple to define and manage

== Usage

=== Defining preferences

To define the preferences for a model, you can do so right within the model:

  class User < ActiveRecord::Base
    preference :hot_salsa
    preference :dark_chocolate, :default => true
    preference :color, :string
    preference :favorite_number
    preference :language, :string, :default => 'English'

In the above model, 5 preferences have been defined:
* hot_salsa
* dark_chocolate
* color
* favorite_number
* language

For each preference, a data type and default value can be specified.  If no
data type is given, it's considered a boolean value.  If no default value is
given, the default is assumed to be nil.

=== Accessing preferences

Once preferences have been defined for a model, they can be accessed either using
the shortcut methods that are generated for each preference or the generic methods
that are not specific to a particular preference.

==== Shortcut methods

There are several shortcut methods that are generated.  They are shown below.

Query methods:
  user.prefers_hot_salsa?         # => false
  user.prefers_dark_chocolate?    # => false

Reader methods:
  user.preferred_color      # => nil
  user.preferred_language   # => "English"

Writer methods:
  user.prefers_hot_salsa = false        # => false
  user.preferred_language = 'English'   # => "English"

==== Generic methods

Each shortcut method is essentially a wrapper for the various generic methods
shown below:

Query method:
  user.prefers?(:hot_salsa)       # => false
  user.prefers?(:dark_chocolate)  # => false

Reader method:
  user.preferred(:color)      # => nil
  user.preferred(:language)   # => "English"

Write method:
  user.set_preference(:hot_salsa, false)      # => false
  user.set_preference(:language, "English")   # => "English"

=== Accessing all preferences

To get the collection of all custom, stored preferences for a particular record,
you can access the +preferences+ has_many association which is automatically


In addition to this, you can get a hash of all stored preferences *and* default
preferences, by accessing the +preference_values+ helper:

  user.preference_values  # => {"language"=>"English", "color"=>nil}

This hash will contain the value for every preference that has been defined for
the model, whether that's the default value or one that has been previously

=== Grouping preferences

In addition to defining generic preferences for the owning record, you can also
group preferences by ActiveRecord objects or arbitrary names.  This is best shown
through an example:

  user = User.find(:first)
  car = Car.find(:first)
  user.preferred_color = 'red', car
  # user.set_preference(:color, 'red', car) # The generic way

This will create a preference for the color "red" for the given car.  In this way,
you can have "color" preferences for different records.

To access the preference for a particular record, you can use the same accessor
methods as before:

  # user.preferred(:color, car) # The generic way

In addition to grouping preferences for a particular record, you can also group
preferences by name.  For example,

  user = User.find(:first)
  user.preferred_color = 'red', 'automobiles'
  user.preferred_color = 'tan', 'clothing'
  user.preferred_color('automobiles')   # => "red"
  user.preferred_color('clothing')      # => "tan"

  user.preference_values                # => {"color"=>nil, "automobiles"=>{"color"=>"red"}, "clothing=>{"color=>"tan"}}
  user.preference_values('automobiles') # => {"color"=>"red"}

=== Saving preferences

Note that preferences are not saved until the owning record is saved.  Preferences
are treated in a similar fashion to attributes.  For example,

  user = user.find(:first)
  user.attributes = {:preferred_color => 'red'}!

Preferences are stored in a separate table called "preferences".

== Testing

Before you can run any tests, the following gem must be installed:
* plugin_test_helper[]

To run against a specific version of Rails:

  rake test RAILS_FRAMEWORK_ROOT=/path/to/rails

== Dependencies

* Rails 2.1 or later
* plugins_plus[]
Something went wrong with that request. Please try again.