Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Adds support for easily creating custom preferences for models
tag: v0.1.2

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 +stored_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 +preferences+ helper:

  user.preferences  # => {"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.preferences                # => {"color"=>nil, "automobiles"=>{"color"=>"red"}, "clothing=>{"color=>"tan"}}
  user.preferences('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.