dm_preferences 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 22afc1090fdd19367b6cce592aef904ddd64f678
4
+ data.tar.gz: d9666d94c3aec78e866f6b4f782708ade93b8f8e
5
+ SHA512:
6
+ metadata.gz: e66a031fb4116289eaeb68ed0a4c616d1460d5c27df3d54f65be940f0d007145f9a2e6c3385f0da16bd2b1c9e0e4fde4d604e70635e126eb3686a40ee40a4d00
7
+ data.tar.gz: 536a0de247d6fdfd73ee9916bd0d56ccd2671a498aeedaec49b8657a8adb95f6755c88007867d07c0b88f2e9f2fb480acf5c9e37a74ceeeee12b903fdd239e5f
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ coverage
3
+ pkg
4
+ rdoc
5
+ test/app_root/log
6
+ test/app_root/script
7
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.8.7
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,86 @@
1
+ == master
2
+
3
+ == 0.5.0 / 2011-08-23
4
+
5
+ * Rails 3 support [Jack Dempsey]
6
+
7
+ == 0.4.2 / 2010-04-17
8
+
9
+ * Fix #preferences lookup not typecasting values
10
+
11
+ == 0.4.1 / 2010-03-07
12
+
13
+ * Add support for per-group default preferences
14
+ * Fix unsaved boolean preferences getting overridden by defaults if value is false
15
+
16
+ == 0.4.0 / 2010-03-07
17
+
18
+ * Add {preference}_changed?, {preference}_was, {preference}_changed, {preference}_will_change!, and reset_{preference}!
19
+ * Add #preferences_changed?, #preferences_changed, and #preference_changes
20
+ * Fix preferences that are reverted externally still getting stored
21
+ * Fix preference definition types not being used to typecast values
22
+ * No longer allow both group and non-group preferences to be looked up at once (except for named scopes)
23
+ * Add support for using Symbols to reference groups
24
+ * Fix #reload not causing unsaved preferences to get reset
25
+ * Raise exception if unknown preference is accessed
26
+ * Rename #set_preference to #write_preference
27
+ * Add caching of preference lookups
28
+ * Fix preferences being stored even if they didn't change
29
+ * Release gems via rake-gemcutter instead of rubyforge
30
+ * Add a generator for db migration to make installation a bit easier [Tim Lowrimore]
31
+ * Add named scopes: #with_preferences and #without_preferences
32
+
33
+ == 0.3.1 / 2009-04-25
34
+
35
+ * Rename Preference#attribute to #name to avoid conflicts with reserved methods in ActiveRecord
36
+
37
+ == 0.3.0 / 2009-04-13
38
+
39
+ * Add dependency on Rails 2.3
40
+ * Remove dependency on plugins_plus
41
+
42
+ == 0.2.0 / 2008-12-14
43
+
44
+ * Remove the PluginAWeek namespace
45
+
46
+ == 0.1.5 / 2008-11-16
47
+
48
+ * Add all prefers/preferred accessors for preferences to be analogous to ActiveRecord column accessors
49
+ * Fix preferences defined in STI subclasses not working [Quinn Shanahan]
50
+
51
+ == 0.1.4 / 2008-10-26
52
+
53
+ * Change how the base module is included to prevent namespacing conflicts
54
+
55
+ == 0.1.3 / 2008-06-29
56
+
57
+ * Add +prefs+ as an alias for +preferences+
58
+ * Fix +preferences+ not properly selecting preferences when a group is specified
59
+ * Improve test coverage
60
+
61
+ == 0.1.2 / 2008-06-22
62
+
63
+ * Remove log files from gems
64
+
65
+ == 0.1.1 / 2008-06-20
66
+
67
+ * Rename preference_values hash to preferences
68
+ * Rename preferences association to stored_preferences
69
+
70
+ == 0.1.0 / 2008-06-19
71
+
72
+ * Avoid string evaluation for dynamic methods
73
+ * Return hashes for the preference_values, e.g.
74
+
75
+ user.preference_values # => {'color' => 'red', 'number' => 11, 'website' => {'background' => 'white', 'foreground' => 'black'}}
76
+ user.preference_values('website') # => {'background' => 'white', 'foreground' => 'black'}
77
+
78
+ * Add more generic grouping of preferences than with just other records, e.g.
79
+
80
+ user.preferred_color('cars')
81
+
82
+ * Remove support for an options hash when specifying :for associations for preference
83
+
84
+ == 0.0.1 / 2008-05-10
85
+
86
+ * Initial public release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://www.rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2009 Aaron Pfeifer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,224 @@
1
+ == preferences http://travis-ci.org/pluginaweek/preferences.png
2
+
3
+ +preferences+ adds support for easily creating custom preferences for models.
4
+
5
+ == Resources
6
+
7
+ API
8
+
9
+ * http://rdoc.info/github/pluginaweek/preferences/master/frames
10
+
11
+ Bugs
12
+
13
+ * http://github.com/pluginaweek/preferences/issues
14
+
15
+ Development
16
+
17
+ * http://github.com/pluginaweek/preferences
18
+
19
+ Testing
20
+
21
+ * http://travis-ci.org/pluginaweek/preferences
22
+
23
+ Source
24
+
25
+ * git://github.com/pluginaweek/preferences.git
26
+
27
+ Mailing List
28
+
29
+ * http://groups.google.com/group/pluginaweek-talk
30
+
31
+ == Description
32
+
33
+ Preferences for models within an application, such as for users, is a pretty
34
+ common idiom. Although the rule of thumb is to keep the number of preferences
35
+ available to a minimum, sometimes it's necessary if you want users to be able to
36
+ disable things like e-mail notifications.
37
+
38
+ Generally, basic preferences can be accomplished through simple designs, such as
39
+ additional columns or a bit vector described and implemented by preference_fu[http://agilewebdevelopment.com/plugins/preferencefu].
40
+ However, as you find the need for non-binary preferences and the number of
41
+ preferences becomes unmanageable as individual columns in the database, the next
42
+ step is often to create a separate "preferences" table. This is where the
43
+ +preferences+ plugin comes in.
44
+
45
+ +preferences+ encapsulates this design by exposing preferences using simple
46
+ attribute accessors on the model, hiding the fact that preferences are stored in
47
+ a separate table and making it dead-simple to define and manage preferences.
48
+
49
+ == Usage
50
+
51
+ === Installation
52
+
53
+ +preferences+ requires an additional database table to work. You can generate
54
+ a migration for this table like so:
55
+
56
+ script/generate preferences
57
+
58
+ Then simply migrate your database:
59
+
60
+ rake db:migrate
61
+
62
+ === Defining preferences
63
+
64
+ To define the preferences for a model, you can do so right within the model:
65
+
66
+ class User < ActiveRecord::Base
67
+ preference :hot_salsa
68
+ preference :dark_chocolate, :default => true
69
+ preference :color, :string
70
+ preference :favorite_number
71
+ preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Spanish'}
72
+ end
73
+
74
+ In the above model, 5 preferences have been defined:
75
+ * hot_salsa
76
+ * dark_chocolate
77
+ * color
78
+ * favorite_number
79
+ * language
80
+
81
+ For each preference, a data type and default value can be specified. If no
82
+ data type is given, it's assumed to be a boolean value. If no default value is
83
+ given, the default is assumed to be nil.
84
+
85
+ === Accessing preferences
86
+
87
+ Once preferences have been defined for a model, they can be accessed either
88
+ using the accessor methods that are generated for each preference or the generic
89
+ methods that are not specific to a particular preference.
90
+
91
+ ==== Accessors
92
+
93
+ There are several shortcut methods that are generated for each preference
94
+ defined on a model. These reflect the same set of methods (attribute accessors)
95
+ that are generated for a model's columns. Examples of these are shown below:
96
+
97
+ Query methods:
98
+ user.prefers_hot_salsa? # => false
99
+ user.preferred_language? # => true
100
+
101
+ Reader methods:
102
+ user.prefers_hot_salsa # => false
103
+ user.preferred_language # => "English"
104
+
105
+ Writer methods:
106
+ user.prefers_hot_salsa = false # => false
107
+ user.preferred_language = 'English' # => "English"
108
+
109
+ ==== Generic methods
110
+
111
+ Each preference accessor is essentially a wrapper for the various generic methods
112
+ shown below:
113
+
114
+ Query method:
115
+ user.prefers?(:hot_salsa) # => false
116
+ user.preferred?(:language) # => true
117
+
118
+ Reader method:
119
+ user.prefers(:hot_salsa) # => false
120
+ user.preferred(:language) # => "English"
121
+
122
+ Write method:
123
+ user.write_preference(:hot_salsa, false) # => false
124
+ user.write_preference(:language, "English") # => "English"
125
+
126
+ === Accessing all preferences
127
+
128
+ To get the collection of all custom, stored preferences for a particular record,
129
+ you can access the +stored_preferences+ has_many association which is automatically
130
+ generated:
131
+
132
+ user.stored_preferences
133
+
134
+ In addition to this, you can get a hash of all stored preferences *and* default
135
+ preferences, by accessing the +preferences+ helper:
136
+
137
+ user.preferences # => {"language"=>"English", "color"=>nil}
138
+
139
+ This hash will contain the value for every preference that has been defined for
140
+ the model, whether that's the default value or one that has been previously
141
+ stored.
142
+
143
+ A short-hand alternative for preferences is also available:
144
+
145
+ user.prefs # => {"language"=>"English", "color"=>nil}
146
+
147
+ === Grouping preferences
148
+
149
+ In addition to defining generic preferences for the owning record, you can also
150
+ group preferences by ActiveRecord objects or arbitrary names. This is best shown
151
+ through an example:
152
+
153
+ user = User.find(:first)
154
+ car = Car.find(:first)
155
+
156
+ user.preferred_color = 'red', car
157
+ # user.write_preference(:color, 'red', car) # The generic way
158
+
159
+ This will create a color preference of "red" for the given car. In this way,
160
+ you can have "color" preferences for different records.
161
+
162
+ To access the preference for a particular record, you can use the same accessor
163
+ methods as before:
164
+
165
+ user.preferred_color(car)
166
+ # user.preferred(:color, car) # The generic way
167
+
168
+ In addition to grouping preferences for a particular record, you can also group
169
+ preferences by name. For example,
170
+
171
+ user = User.find(:first)
172
+
173
+ user.preferred_color = 'red', :automobiles
174
+ user.preferred_color = 'tan', :clothing
175
+
176
+ user.preferred_color(:automobiles) # => "red"
177
+ user.preferred_color(:clothing) # => "tan"
178
+
179
+ user.preferences(:automobiles) # => {"color"=>"red"}
180
+
181
+ === Saving preferences
182
+
183
+ Note that preferences are not saved until the owning record is saved.
184
+ Preferences are treated in a similar fashion to attributes. For example,
185
+
186
+ user = user.find(:first)
187
+ user.attributes = {:prefers_hot_salsa => false, :preferred_color => 'red'}
188
+ user.save!
189
+
190
+ Preferences are stored in a separate table called "preferences".
191
+
192
+ === Tracking changes
193
+
194
+ Similar to ActiveRecord attributes, unsaved changes to preferences can be
195
+ tracked. For example,
196
+
197
+ user.preferred_language # => "English"
198
+ user.preferred_language_changed? # => false
199
+ user.preferred_language = 'Spanish'
200
+ user.preferred_language_changed? # => true
201
+ user.preferred_language_was # => "English"
202
+ user.preferred_language_change # => ["English", "Spanish"]
203
+ user.reset_preferred_language!
204
+ user.preferred_language # => "English"
205
+
206
+ Assigning the same value leaves the preference unchanged:
207
+
208
+ user.preferred_language # => "English"
209
+ user.preferred_language = 'English'
210
+ user.preferred_language_changed? # => false
211
+ user.preferred_language_change # => nil
212
+
213
+ == Testing
214
+
215
+ Before you can run any tests, the following gem must be installed:
216
+ * plugin_test_helper[http://github.com/pluginaweek/plugin_test_helper]
217
+
218
+ To run against a specific version of Rails:
219
+
220
+ rake test RAILS_FRAMEWORK_ROOT=/path/to/rails
221
+
222
+ == Dependencies
223
+
224
+ * 0.5.6 for Rails 4.1
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ desc 'Default: run all tests.'
7
+ task :default => :test
8
+
9
+ desc "Test preferences."
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.test_files = Dir['test/**/*_test.rb']
13
+ t.verbose = true
14
+ end
15
+
16
+ begin
17
+ require 'rcov/rcovtask'
18
+ namespace :test do
19
+ desc "Test preferences with Rcov."
20
+ Rcov::RcovTask.new(:rcov) do |t|
21
+ t.libs << 'lib'
22
+ t.test_files = Dir['test/**/*_test.rb']
23
+ t.rcov_opts << '--exclude="^(?!lib/|app/)"'
24
+ t.verbose = true
25
+ end
26
+ end
27
+ rescue LoadError
28
+ end
29
+
30
+ desc "Generate documentation for preferences."
31
+ Rake::RDocTask.new(:rdoc) do |rdoc|
32
+ rdoc.rdoc_dir = 'rdoc'
33
+ rdoc.title = 'preferences'
34
+ rdoc.options << '--line-numbers' << '--inline-source' << '--main=README.rdoc'
35
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb', 'app/**/*.rb')
36
+ end
@@ -0,0 +1,65 @@
1
+ # Represents a preferred value for a particular preference on a model.
2
+ #
3
+ # == Grouped preferences
4
+ #
5
+ # In addition to simple named preferences, preferences can also be grouped by
6
+ # a particular value, be it a string or ActiveRecord object. For example, a
7
+ # User may have a preferred color for a particular Car. In this case, the
8
+ # +owner+ is the User record, the +name+ is "color", and the +group+ is the
9
+ # Car record. This allows preferences to have a sort of context around them.
10
+ class Preference < ActiveRecord::Base
11
+ belongs_to :owner, :polymorphic => true
12
+ belongs_to :group, :polymorphic => true
13
+
14
+ validates_presence_of :name, :owner_id, :owner_type
15
+ validates_presence_of :group_type, :if => :group_id?
16
+
17
+ class << self
18
+ # Splits the given group into its corresponding id and type. For simple
19
+ # primitives, the id will be nil. For complex types, specifically
20
+ # ActiveRecord objects, the id is the unique identifier stored in the
21
+ # database for the record.
22
+ #
23
+ # For example,
24
+ #
25
+ # Preference.split_group('google') # => [nil, "google"]
26
+ # Preference.split_group(1) # => [nil, 1]
27
+ # Preference.split_group(User.find(1)) # => [1, "User"]
28
+ def split_group(group = nil)
29
+ if group.is_a?(ActiveRecord::Base)
30
+ group_id, group_type = group.id, group.class.base_class.name.to_s
31
+ else
32
+ group_id, group_type = nil, group.is_a?(Symbol) ? group.to_s : group
33
+ end
34
+
35
+ [group_id, group_type]
36
+ end
37
+ end
38
+
39
+ # The definition of the preference as defined in the owner's model
40
+ def definition
41
+ # Optimize number of queries to the database by only looking up the actual
42
+ # owner record for STI cases when the definition can't be found in the
43
+ # stored owner type class
44
+ owner_type && (find_definition(owner_type.constantize) || find_definition(owner.class))
45
+ end
46
+
47
+ # Typecasts the value depending on the preference definition's declared type
48
+ def value
49
+ value = read_attribute(:value)
50
+ value = definition.type_cast(value) if definition
51
+ value
52
+ end
53
+
54
+ # Only searches for the group record if the group id is specified
55
+ def group_with_optional_lookup
56
+ group_id ? group_without_optional_lookup : group_type
57
+ end
58
+ alias_method_chain :group, :optional_lookup
59
+
60
+ private
61
+ # Finds the definition for this preference in the given owner class.
62
+ def find_definition(owner_class)
63
+ owner_class.respond_to?(:preference_definitions) && owner_class.preference_definitions[name]
64
+ end
65
+ end