<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>db/migrate/001_create_preferences.rb</filename>
    </added>
    <added>
      <filename>lib/preferences.rb</filename>
    </added>
    <added>
      <filename>lib/preferences/preference_definition.rb</filename>
    </added>
    <added>
      <filename>test/app_root/app/models/car.rb</filename>
    </added>
    <added>
      <filename>test/app_root/app/models/user.rb</filename>
    </added>
    <added>
      <filename>test/app_root/config/environment.rb</filename>
    </added>
    <added>
      <filename>test/app_root/db/migrate/001_create_users.rb</filename>
    </added>
    <added>
      <filename>test/app_root/db/migrate/002_create_cars.rb</filename>
    </added>
    <added>
      <filename>test/app_root/db/migrate/003_migrate_preferences_to_version_1.rb</filename>
    </added>
    <added>
      <filename>test/factory.rb</filename>
    </added>
    <added>
      <filename>test/functional/preferences_test.rb</filename>
    </added>
    <added>
      <filename>test/test_helper.rb</filename>
    </added>
    <added>
      <filename>test/unit/preference_definition_test.rb</filename>
    </added>
    <added>
      <filename>test/unit/preference_test.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,2 +1,5 @@
 *SVN*
 
+*0.0.1* (May 10th, 2008)
+
+* Initial public release</diff>
      <filename>CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-Copyright (c) 2006-2007 Aaron Pfeifer &amp; Neil Abraham
+Copyright (c) 2008 Aaron Pfeifer
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</diff>
      <filename>MIT-LICENSE</filename>
    </modified>
    <modified>
      <diff>@@ -1,46 +1,146 @@
-== acts_as_preferenced
+== preferences
 
-acts_as_preferenced .
++preferences+ adds support for easily creating custom preferences for models.
 
 == Resources
 
 Wiki
 
-* http://wiki.pluginaweek.org/Acts_as_preferenced
-
-Announcement
-
-* http://www.pluginaweek.org/
+* http://wiki.pluginaweek.org/Preferences
 
 Source
 
-* http://svn.pluginaweek.org/trunk/plugins/active_record/acts/acts_as_preferenced
+* http://svn.pluginaweek.org/trunk/plugins/preferences
 
 Development
 
-* http://dev.pluginaweek.org/browser/trunk/plugins/active_record/acts/acts_as_preferenced
+* http://dev.pluginaweek.org/browser/trunk/preferences
 
 == 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 accomplish through simple designs, such as
+additional columns or a bit vector described and implemented by preference_fu[http://agilewebdevelopment.com/plugins/preferencefu].
+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 seprate &quot;preferences&quot; 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
+preferences.
+
+== Usage
+
+=== Defining preferences
+
+To define the preferences for a model, you can do so right within the model:
+
+  class User &lt; ActiveRecord::Base
+    preference :hot_salsa
+    preference :dark_chocolate, :default =&gt; true
+    preference :color, :string
+    preference :favorite_number
+    preference :language, :string, :default =&gt; 'English'
+  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 considered a boolean value.  If not 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?         # =&gt; false
+  user.prefers_dark_chocolate?    # =&gt; false
+
+Reader methods:
+  user.preferred_color      # =&gt; nil
+  user.preferred_language   # =&gt; &quot;English&quot;
+
+Writer methods:
+  user.prefers_hot_salsa = false        # =&gt; false
+  user.preferred_language = 'English'   # =&gt; &quot;English&quot;
+
+==== Generic methods
+
+Each shortcut method is essentially a wrapper for the various generic methods
+show below:
+
+Query method:
+  user.prefers?(:hot_salsa)       # =&gt; false
+  user.prefers?(:dark_chocolate)  # =&gt; false
+
+Reader method:
+  user.preferred(:color)      # =&gt; nil
+  user.preferred(:language)   # =&gt; &quot;English&quot;
+
+Write method:
+  user.set_preference(:hot_salsa, false)      # =&gt; false
+  user.set_preference(:language, &quot;English&quot;)   # =&gt; &quot;English&quot;
+
+=== Accessing all preferences
+
+To get the collection of all preferences for a particular user, you can access
+the +preferences+ has_many association which is automatically generated:
+
+  user.preferences
+
+=== Preferences for other records
+
+In addition to defining generic preferences for the owning record, you can also
+define preferences for other records.  This is best shown through an example:
+
+  user = User.find(:first)
+  car = Car.find(:first)
+  
+  user.preferred_color = 'red', {:for =&gt; car}
+  # user.set_preference(:color, 'red', :for =&gt; car) # The generic way
+
+This will create a preference for the color &quot;red&quot; for the given car.  In this way,
+you can have &quot;color&quot; preferences for different records.
+
+To access the preference for a particular record, you can use the same accessor
+methods as before:
+
+  user.preferred_color(:for =&gt; car)
+  # user.preferred(:color, :for =&gt; car) # The generic way
+
+=== 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,
 
-== Examples
+  user = user.find(:first)
+  user.attributes = {:preferred_color =&gt; 'red'}
+  user.save!
 
-user.preferred_email_address (text)
-user.prefers_milk? (boolean)
-user.preferred_color (enum)
+Preferences are stored in a separate table assumed to be called &quot;preferences&quot;.
 
-preference :email_address (infers :any)
-preference :email_address,  :any
-preference :milk,           :boolean, :default =&gt; true
-preference :color,          :enum,    :in =&gt; %w(red white blue), :default =&gt; 'red'
+== Testing
 
-# If user can choose what products to hide:
-user.prefers_hidden_for?(product)
-user.preferred_color_for?(product)
+Before you can run any tests, the following gem must be installed:
+* plugin_test_helper[http://wiki.pluginaweek.org/Plugin_test_helper]
 
-preference :hiddden, :boolean, :default =&gt; false, :for =&gt; 'Product'
-preference :color,   :enum,    :in =&gt; %w(red white blue), :default =&gt; 'red', :for =&gt; 'Product'
+== Dependencies
 
-# If you want to specify different specs for a different type
-preference :color,   :enum,    :in =&gt; %w(black white), :default =&gt; 'white', :for =&gt; 'Car'
\ No newline at end of file
+* plugins_plus[http://wiki.pluginaweek.org/Plugins_plus]</diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,7 @@ require 'rake/rdoctask'
 require 'rake/gempackagetask'
 require 'rake/contrib/sshpublisher'
 
-PKG_NAME           = 'acts_as_preferenced'
+PKG_NAME           = 'preferences'
 PKG_VERSION        = '0.0.1'
 PKG_FILE_NAME      = &quot;#{PKG_NAME}-#{PKG_VERSION}&quot;
 RUBY_FORGE_PROJECT = 'pluginaweek'
@@ -11,17 +11,18 @@ RUBY_FORGE_PROJECT = 'pluginaweek'
 desc 'Default: run unit tests.'
 task :default =&gt; :test
 
-desc 'Test the acts_as_preferenced plugin.'
+desc 'Test the preferences plugin.'
 Rake::TestTask.new(:test) do |t|
   t.libs &lt;&lt; 'lib'
   t.pattern = 'test/**/*_test.rb'
   t.verbose = true
 end
 
-desc 'Generate documentation for the acts_as_preferenced plugin.'
+desc 'Generate documentation for the preferences plugin.'
 Rake::RDocTask.new(:rdoc) do |rdoc|
   rdoc.rdoc_dir = 'rdoc'
-  rdoc.title    = 'ActsAsPreferenced'
+  rdoc.title    = 'Preferences'
+  rdoc.template = '../rdoc_template.rb'
   rdoc.options &lt;&lt; '--line-numbers' &lt;&lt; '--inline-source'
   rdoc.rdoc_files.include('README')
   rdoc.rdoc_files.include('lib/**/*.rb')
@@ -31,16 +32,16 @@ spec = Gem::Specification.new do |s|
   s.name            = PKG_NAME
   s.version         = PKG_VERSION
   s.platform        = Gem::Platform::RUBY
-  s.summary         = ''
+  s.summary         = 'Adds support for easily creating custom preferences for models'
   
-  s.files           = FileList['{app,db,lib,tasks,test}/**/*'].to_a + %w(init.rb MIT-LICENSE Rakefile README)
+  s.files           = FileList['{app,lib,test}/**/*'].to_a + %w(CHANGELOG init.rb MIT-LICENSE Rakefile README)
   s.require_path    = 'lib'
-  s.autorequire     = 'acts_as_preferenced'
+  s.autorequire     = 'preferences'
   s.has_rdoc        = true
   s.test_files      = Dir['test/**/*_test.rb']
   
-  s.author          = 'Aaron Pfeifer, Neil Abraham'
-  s.email           = 'info@pluginaweek.org'
+  s.author          = 'Aaron Pfeifer'
+  s.email           = 'aaron@pluginaweek.org'
   s.homepage        = 'http://www.pluginaweek.org'
 end
   
@@ -52,16 +53,16 @@ end
 
 desc 'Publish the beta gem'
 task :pgem =&gt; [:package] do
-  Rake::SshFilePublisher.new('pluginaweek@pluginaweek.org', '/home/pluginaweek/gems.pluginaweek.org/gems', 'pkg', &quot;#{PKG_FILE_NAME}.gem&quot;).upload
+  Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', &quot;#{PKG_FILE_NAME}.gem&quot;).upload
 end
 
 desc 'Publish the API documentation'
 task :pdoc =&gt; [:rdoc] do
-  Rake::SshDirPublisher.new('pluginaweek@pluginaweek.org', &quot;/home/pluginaweek/api.pluginaweek.org/#{PKG_NAME}&quot;, 'rdoc').upload
+  Rake::SshDirPublisher.new('aaron@pluginaweek.org', &quot;/home/aaron/api.pluginaweek.org/public/#{PKG_NAME}&quot;, 'rdoc').upload
 end
 
 desc 'Publish the API docs and gem'
-task :publish =&gt; [:pdoc, :release]
+task :publish =&gt; [:pgem, :pdoc, :release]
 
 desc 'Publish the release files to RubyForge.'
 task :release =&gt; [:gem, :package] do
@@ -76,4 +77,4 @@ task :release =&gt; [:gem, :package] do
     
     ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
   end
-end
\ No newline at end of file
+end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,26 +1,34 @@
+# Represents a preferred value for a particular preference on a model.
 # 
+# == Targeted preferences
+# 
+# In addition to simple named preferences, preferences can also be targeted for
+# a particular record.  For example, a User may have a preferred color for a
+# particular Car.  In this case, the +owner+ is the User, the +preference+ is
+# the color, and the +target+ is the Car.  This allows preferences to have a sort
+# of context around them.
 class Preference &lt; ActiveRecord::Base
-  belongs_to            :definition,
-                          :class_name =&gt; 'PreferenceDefinition',
-                          :foreign_key =&gt; 'definition_id'
-  belongs_to            :owner,
-                          :polymorphic =&gt; true
-  belongs_to            :preferenced,
-                          :polymorphic =&gt; true
+  belongs_to  :owner,
+                :polymorphic =&gt; true
+  belongs_to  :preferenced,
+                :polymorphic =&gt; true
   
-  validates_presence_of :definition_id,
+  validates_presence_of :attribute,
                         :owner_id,
-                        :preferenced_id,
-                        :preferenced_type
-                        
-  delegate              :default_value,
-                        :data_type,
-                        :possible_values,
-                          :to =&gt; :definition
+                        :owner_type
+  validates_presence_of :preferenced_id,
+                        :preferenced_type,
+                          :if =&gt; Proc.new {|p| p.preferenced_id? || p.preferenced_type?}
+  
+  # The definition for the attribute
+  def definition
+    owner_type.constantize.preference_definitions[attribute] if owner_type
+  end
   
-  # 
-  def validate
-    @errors.add 'preferenced_type', 'is not a valid type' unless definition.valid_preference?(preferenced_type)
-    @errors.add 'value', &quot;must be #{possible_values.to_sentence(:connector =&gt; 'or')}&quot; unless definition.valid_value?(value)
+  # Typecasts the value depending on the preference definition's declared type
+  def value
+    value = read_attribute(:value)
+    value = definition.type_cast(value) if definition
+    value
   end
-end
\ No newline at end of file
+end</diff>
      <filename>app/models/preference.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1 @@
-require 'acts_as_preferenced'
\ No newline at end of file
+require 'preferences'</diff>
      <filename>init.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>app/models/preference_definition.rb</filename>
    </removed>
    <removed>
      <filename>db/migrate/001_create_preference_definitions.rb</filename>
    </removed>
    <removed>
      <filename>db/migrate/002_create_preferences.rb</filename>
    </removed>
    <removed>
      <filename>lib/acts_as_preferenced.rb</filename>
    </removed>
    <removed>
      <filename>test/acts_as_preferenced_test.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>812e7ab1192260e02472cc4c8d65a337e3069842</id>
    </parent>
  </parents>
  <author>
    <name>Aaron Pfeifer</name>
    <email>aaron.pfeifer@gmail.com</email>
  </author>
  <url>http://github.com/pluginaweek/preferences/commit/ffcf63dc83110fa7c2ffcd6e12368d2e5d2069dc</url>
  <id>ffcf63dc83110fa7c2ffcd6e12368d2e5d2069dc</id>
  <committed-date>2008-05-10T18:36:51-07:00</committed-date>
  <authored-date>2008-05-10T18:36:51-07:00</authored-date>
  <message>Rename to preferences
Add documentation
Completely rewrite from scratch</message>
  <tree>e270ad4c87240bbb41166c1c3e3f4ecc092a5fec</tree>
  <committer>
    <name>Aaron Pfeifer</name>
    <email>aaron.pfeifer@gmail.com</email>
  </committer>
</commit>
