Module: Preferences::MacroMethods
- Defined in:
- lib/preferences.rb
Instance Method Summary collapse
-
#preference(name, *args) ⇒ Object
Defines a new preference for all records in the model.
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. This will not include default preferences unless they have been explicitly set.
Generated accessors
In addition to calling prefers? and preferred on a record, you can also use the shortcut accessor methods that are generated when a preference is defined. For example,
class User < ActiveRecord::Base
preference :notifications
end
…generates the following methods:
-
prefers_notifications?- Whether a value has been specified, i.e.record.prefers?(:notifications) -
prefers_notifications- The actual value stored, i.e.record.prefers(:notifications) -
prefers_notifications=(value)- Sets a new value, i.e.record.set_preference(:notifications, value) -
preferred_notifications?- Whether a value has been specified, i.e.record.preferred?(:notifications) -
preferred_notifications- The actual value stored, i.e.record.preferred(:notifications) -
preferred_notifications=(value)- Sets a new value, i.e.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 accessing boolean preferences, while preferred_color is better for accessing non-boolean preferences.
Example:
user = User.find(:first)
user.prefers_notifications? # => false
user.prefers_notifications # => false
user.preferred_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.preferred_color?(car) # => true
user.save! # => true
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/preferences.rb', line 117 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 Preferences::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 accessor methods, making sure that the name # is method-safe in terms of what characters are allowed name = name.gsub(/[^A-Za-z0-9_-]/, '').underscore # Query lookup define_method("preferred_#{name}?") do |*group| preferred?(name, group.first) end alias_method "prefers_#{name}?", "preferred_#{name}?" # Reader define_method("preferred_#{name}") do |*group| preferred(name, group.first) end alias_method "prefers_#{name}", "preferred_#{name}" # Writer define_method("preferred_#{name}=") do |*args| set_preference(*([name] + [args].flatten)) end alias_method "prefers_#{name}=", "preferred_#{name}=" definition end |