Module: Spree::Preferences::ModelHooks::MacroMethods

Defined in:
lib/spree_core/preferences/model_hooks.rb

Instance Method Summary collapse

Instance Method Details

#preference(name, *args) ⇒ Object

Defines a new preference for all records in the model. By default, preferences are assumed to have a boolean data type, so all values will be typecasted to true/false based on ActiveRecord rules.

Configuration options:

  • default - The default value for the preference. Default is nil.

Examples

The example below shows the various ways to define a preference for a particular model.

class User < ActiveRecord::Base
  preference :notifications, :default => false
  preference :color, :string, :default => 'red'
  preference :favorite_number, :integer
  preference :data, :any # Allows any data type to be stored
end

All preferences are also inherited by subclasses.

Associations

After the first preference is defined, the following associations are created for the model:

  • stored_preferences - A collection of all the custom preferences specified for a record

Generated shortcut methods

In addition to calling prefers? and preferred on a record, you can also use the shortcut methods that are generated when a preference is defined. For example,

class User < ActiveRecord::Base
  preference :notifications
end

…generates the following methods:

  • prefers_notifications? - The same as calling record.prefers?(:notifications)

  • prefers_notifications=(value) - The same as calling record.set_preference(:notifications, value)

  • preferred_notifications - The same as called record.preferred(:notifications)

  • preferred_notifications=(value) - The same as calling record.set_preference(:notifications, value)

Notice that there are two tenses used depending on the context of the preference. Conventionally, prefers_notifications? is better for boolean preferences, while preferred_color is better for non-boolean preferences.

Example:

user = User.find(:first)
user.prefers_notifications?         # => false
user.prefers_color?                 # => true
user.preferred_color                # => 'red'
user.preferred_color = 'blue'       # => 'blue'

user.prefers_notifications = true

car = Car.find(:first)
user.preferred_color = 'red', car   # => 'red'
user.preferred_color(car)           # => 'red'
user.prefers_color?(car)            # => true

user.save!  # => true


97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/spree_core/preferences/model_hooks.rb', line 97

def preference(name, *args)
  unless included_modules.include?(InstanceMethods)
    class_inheritable_hash :preference_definitions
    self.preference_definitions = {}

    class_inheritable_hash :default_preferences
    self.default_preferences = {}

    has_many  :stored_preferences, :as => :owner, :class_name => 'Preference'

    after_save :update_preferences

    include Spree::Preferences::ModelHooks::InstanceMethods
  end

  # Create the definition
  name = name.to_s
  definition = PreferenceDefinition.new(name, *args)
  self.preference_definitions[name] = definition
  self.default_preferences[name] = definition.default_value

  # Create short-hand helper methods, making sure that the attribute
  # is method-safe in terms of what characters are allowed
  name = name.gsub(/[^A-Za-z0-9_-]/, '').underscore

  # Query lookup
  define_method("prefers_#{name}?") do |*group|
    prefers?(name, group.first)
  end

  # Writer
  define_method("prefers_#{name}=") do |*args|
    set_preference(*([name] + [args].flatten))
  end
  alias_method "preferred_#{name}=", "prefers_#{name}="

  # Reader
  define_method("preferred_#{name}") do |*group|
    preferred(name, group.first)
  end

  definition
end