Spree Commerce

Try It Now

Spree Preferences Refactored

Posted on December 08, 2011 by cmar

We have refactored Spree Preferences to improve performance and simplify
code for applicaitons and extensions. The previous interfaces have been
maintained so no code changes should be required. The underlying classes
have been completely rewritten.

The new underlying classes are much simpiler and approach preference
storage with the concept that preferences are read much more often
they are written. We use Rails caching to maintain key/value pairs
in memory for fast access. Changes are persisted to the database and
loaded during initalization to pre-populate the cache.

There is a new utility class Spree::Preferences::Configuration for
extensions to create their own namespaced preferences.

<p>MyExt::Configuration &lt; Spree::Preferences::Configuration<br />
  preference :show_ads, :boolean, :default =&gt; true<br />
<p><span class="caps">MYEXT</span>::<span class="caps">CONFIG</span> = MyExt::Configuration.new<br />
<span class="caps">MYEXT</span>::<span class="caps">CONFIG</span>.show_ads = false</p>

The above preference will share the same cache and database table as the
Spree General Configuration. It will be keyed as

We continue to store preferences for model instances. You can define
a preference for your model. Each instance will use the default value
unless a new value is set. The instance specific preference will be
immediately persisted to the database and keyed with the id

<p>class User &lt; ActiveRecord::Base<br />
  preference :email_notifications, :boolean, :default =&gt; true<br />
  preference :favorite_food, :string, :default =&gt; &#8216;beer&#8217;<br />
<p>user = User.create</p>
	<li>reading<br />
user.prefers_email_notifications? # =&gt; true<br />
user.preferred_favorite_food # =&gt; &#8216;beer&#8217;<br />
user.get_preference :favorite_food #= &#8216;beer&#8217;</li>
	<li>writing<br />
user.prefers_email_notifications = false<br />
user.preferred_favorite_food = &#8216;meatloaf&#8217;<br />
user.set_preference :favorite_food, &#8216;meatloaf&#8217;</li>
	<li>definition<br />
user.preferred_favorite_food_default # =&gt; &#8216;beer&#8217;<br />
user.preferred_favorite_food_type # =&gt; :string</li>

We have included a migration that will convert your previous preferences
to the new format.