• Stars
    star
    161
  • Rank 233,470 (Top 5 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 16 years ago
  • Updated over 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Adds support for easily creating custom preferences for models

preferences ¶ ↑

preferences adds support for easily creating custom preferences for models.

Resources¶ ↑

API

Bugs

Development

Testing

Source

  • git://github.com/pluginaweek/preferences.git

Mailing List

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 exposing preferences using simple attribute accessors on the model, hiding the fact that preferences are stored in a separate table and making it dead-simple to define and manage preferences.

Usage¶ ↑

Installation¶ ↑

preferences requires an additional database table to work. You can generate a migration for this table like so:

script/generate preferences

Then simply migrate your database:

rake db:migrate

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', :group_defaults => {:chat => 'Spanish'}
end

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 assumed to be 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 accessor methods that are generated for each preference or the generic methods that are not specific to a particular preference.

Accessors¶ ↑

There are several shortcut methods that are generated for each preference defined on a model. These reflect the same set of methods (attribute accessors) that are generated for a model’s columns. Examples of these are shown below:

Query methods:

user.prefers_hot_salsa?         # => false
user.preferred_language?        # => true

Reader methods:

user.prefers_hot_salsa          # => false
user.preferred_language         # => "English"

Writer methods:

user.prefers_hot_salsa = false        # => false
user.preferred_language = 'English'   # => "English"

Generic methods¶ ↑

Each preference accessor is essentially a wrapper for the various generic methods shown below:

Query method:

user.prefers?(:hot_salsa)     # => false
user.preferred?(:language)    # => true

Reader method:

user.prefers(:hot_salsa)      # => false
user.preferred(:language)     # => "English"

Write method:

user.write_preference(:hot_salsa, false)      # => false
user.write_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 generated:

user.stored_preferences

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 stored.

A short-hand alternative for preferences is also available:

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

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.write_preference(:color, 'red', car) # The generic way

This will create a color preference of “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)
# 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(: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 = {:prefers_hot_salsa => false, :preferred_color => 'red'}
user.save!

Preferences are stored in a separate table called “preferences”.

Tracking changes¶ ↑

Similar to ActiveRecord attributes, unsaved changes to preferences can be tracked. For example,

user.preferred_language               # => "English"
user.preferred_language_changed?      # => false
user.preferred_language = 'Spanish'
user.preferred_language_changed?      # => true
user.preferred_language_was           # => "English"
user.preferred_language_change        # => ["English", "Spanish"]
user.reset_preferred_language!
user.preferred_language               # => "English"

Assigning the same value leaves the preference unchanged:

user.preferred_language               # => "English"
user.preferred_language = 'English'
user.preferred_language_changed?      # => false
user.preferred_language_change        # => nil

Testing¶ ↑

Before you can run any tests, the following gem must be installed:

To run against a specific version of Rails:

rake test RAILS_FRAMEWORK_ROOT=/path/to/rails

Dependencies¶ ↑

  • Rails 2.3 or later

More Repositories

1

state_machine

Adds support for creating state machines for attributes on any Ruby class
Ruby
3,739
star
2

has_messages

Demonstrates a reference implementation for sending messages between users
Ruby
92
star
3

table_helper

Adds a helper method for generating HTML tables from collections
Ruby
71
star
4

encrypted_strings

Provides dead-simple string encryption/decryption syntax
Ruby
43
star
5

enumerate_by

Adds support for declaring an ActiveRecord class as an enumeration
Ruby
38
star
6

has_addresses

Demonstrates a reference implementation for handling countries, regions, and addresses
Ruby
32
star
7

validates_as_email_address

Adds support for validating the format/length of email addresses
Ruby
27
star
8

plugin_test_helper

Simplifies plugin testing by creating an isolated Rails environment that simulates its usage in a real application
Ruby
25
star
9

memorable_strings

Generates strings that can be easily remembered
Ruby
22
star
10

menu_helper

Adds a helper method for generating a menubar
Ruby
20
star
11

encrypted_attributes

Adds support for automatically encrypting ActiveRecord attributes
Ruby
19
star
12

has_phone_numbers

Demonstrates a reference implementation for handling phone numbers
Ruby
18
star
13

has_ratings

Demonstrates a reference implementation for handling ratings
Ruby
10
star
14

has_emails

Demonstrates a reference implementation for sending emails with logging and asynchronous support
Ruby
10
star
15

polymorphic_identity

Dynamically generates aliases for polymorphic associations based on the class names of those associations
Ruby
9
star
16

has_roles

Demonstrates a reference implementation for handling role management
Ruby
8
star
17

tiny_mce_helper

Adds helper methods for creating the TinyMCE initialization script
Ruby
8
star
18

smart_field_constraints

Intelligently applies a maxlength attribute for text fields based on column constraints and validations
Ruby
7
star
19

attribute_predicates

Adds automatic generation of predicate methods when defining attributes
Ruby
6
star
20

styled_inputs

Adds automated styling of input fields with css classes
Ruby
3
star
21

module_creation_helper

Adds a helper method for creating new modules and classes at runtime
Ruby
2
star