preferences 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +5 -0
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/lib/preferences.rb +16 -14
- data/lib/preferences/preference_definition.rb +8 -3
- data/test/functional/preferences_test.rb +37 -40
- data/test/unit/preference_definition_test.rb +18 -0
- data/test/unit/preference_test.rb +0 -2
- metadata +1 -1
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
== master
|
2
2
|
|
3
|
+
== 0.4.1 / 2010-03-07
|
4
|
+
|
5
|
+
* Add support for per-group default preferences
|
6
|
+
* Fix unsaved boolean preferences getting overridden by defaults if value is false
|
7
|
+
|
3
8
|
== 0.4.0 / 2010-03-07
|
4
9
|
|
5
10
|
* Add {preference}_changed?, {preference}_was, {preference}_changed, {preference}_will_change!, and reset_{preference}!
|
data/README.rdoc
CHANGED
@@ -60,7 +60,7 @@ To define the preferences for a model, you can do so right within the model:
|
|
60
60
|
preference :dark_chocolate, :default => true
|
61
61
|
preference :color, :string
|
62
62
|
preference :favorite_number
|
63
|
-
preference :language, :string, :default => 'English'
|
63
|
+
preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Spanish'}
|
64
64
|
end
|
65
65
|
|
66
66
|
In the above model, 5 preferences have been defined:
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'rake/gempackagetask'
|
|
6
6
|
|
7
7
|
spec = Gem::Specification.new do |s|
|
8
8
|
s.name = 'preferences'
|
9
|
-
s.version = '0.4.
|
9
|
+
s.version = '0.4.1'
|
10
10
|
s.platform = Gem::Platform::RUBY
|
11
11
|
s.summary = 'Adds support for easily creating custom preferences for ActiveRecord models'
|
12
12
|
s.description = s.summary
|
data/lib/preferences.rb
CHANGED
@@ -51,6 +51,9 @@ module Preferences
|
|
51
51
|
#
|
52
52
|
# Configuration options:
|
53
53
|
# * <tt>:default</tt> - The default value for the preference. Default is nil.
|
54
|
+
# * <tt>:group_defaults</tt> - Defines the default values to use for various
|
55
|
+
# groups. This should map group_name -> defaults. For ActiveRecord groups,
|
56
|
+
# use the class name.
|
54
57
|
#
|
55
58
|
# == Examples
|
56
59
|
#
|
@@ -59,7 +62,7 @@ module Preferences
|
|
59
62
|
#
|
60
63
|
# class User < ActiveRecord::Base
|
61
64
|
# preference :notifications, :default => false
|
62
|
-
# preference :color, :string, :default => 'red'
|
65
|
+
# preference :color, :string, :default => 'red', :group_defaults => {:car => 'black'}
|
63
66
|
# preference :favorite_number, :integer
|
64
67
|
# preference :data, :any # Allows any data type to be stored
|
65
68
|
# end
|
@@ -152,9 +155,6 @@ module Preferences
|
|
152
155
|
class_inheritable_hash :preference_definitions
|
153
156
|
self.preference_definitions = {}
|
154
157
|
|
155
|
-
class_inheritable_hash :default_preferences
|
156
|
-
self.default_preferences = {}
|
157
|
-
|
158
158
|
has_many :stored_preferences, :as => :owner, :class_name => 'Preference'
|
159
159
|
|
160
160
|
after_save :update_preferences
|
@@ -171,7 +171,6 @@ module Preferences
|
|
171
171
|
name = name.to_s
|
172
172
|
definition = PreferenceDefinition.new(name, *args)
|
173
173
|
self.preference_definitions[name] = definition
|
174
|
-
self.default_preferences[name] = definition.default_value
|
175
174
|
|
176
175
|
# Create short-hand accessor methods, making sure that the name
|
177
176
|
# is method-safe in terms of what characters are allowed
|
@@ -249,11 +248,12 @@ module Preferences
|
|
249
248
|
end
|
250
249
|
|
251
250
|
preferences.each do |(group, preference), value|
|
251
|
+
group_id, group_type = Preference.split_group(group)
|
252
252
|
preference = preference.to_s
|
253
|
-
|
254
|
-
|
253
|
+
definition = preference_definitions[preference.to_s]
|
254
|
+
value = definition.type_cast(value)
|
255
|
+
is_default = definition.default_value(group_type) == value
|
255
256
|
|
256
|
-
group_id, group_type = Preference.split_group(group)
|
257
257
|
table = "preferences_#{group_id}_#{group_type}_#{preference}"
|
258
258
|
|
259
259
|
# Since each preference is a different record, they need their own
|
@@ -303,19 +303,21 @@ module Preferences
|
|
303
303
|
# user.preferences(:cars)
|
304
304
|
# => {"language=>"English", "color"=>"red"}
|
305
305
|
def preferences(group = nil)
|
306
|
+
preferences = preferences_group(group)
|
307
|
+
|
306
308
|
unless preferences_group_loaded?(group)
|
307
|
-
preferences = preferences_group(group)
|
308
|
-
|
309
309
|
group_id, group_type = Preference.split_group(group)
|
310
310
|
find_preferences(:group_id => group_id, :group_type => group_type).each do |preference|
|
311
|
-
preferences[preference.name]
|
311
|
+
preferences[preference.name] = preference.value unless preferences.include?(preference.name)
|
312
312
|
end
|
313
313
|
|
314
314
|
# Add defaults
|
315
|
-
|
315
|
+
preference_definitions.each do |name, definition|
|
316
|
+
preferences[name] = definition.default_value(group_type) unless preferences.include?(name)
|
317
|
+
end
|
316
318
|
end
|
317
319
|
|
318
|
-
|
320
|
+
preferences.dup
|
319
321
|
end
|
320
322
|
|
321
323
|
# Queries whether or not a value is present for the given preference.
|
@@ -374,7 +376,7 @@ module Preferences
|
|
374
376
|
group_id, group_type = Preference.split_group(group)
|
375
377
|
preference = find_preferences(:name => name, :group_id => group_id, :group_type => group_type).first unless preferences_group_loaded?(group)
|
376
378
|
|
377
|
-
value = preference ? preference.value : preference_definitions[name].default_value
|
379
|
+
value = preference ? preference.value : preference_definitions[name].default_value(group_type)
|
378
380
|
preferences_group(group)[name] = value
|
379
381
|
end
|
380
382
|
|
@@ -6,12 +6,17 @@ module Preferences
|
|
6
6
|
|
7
7
|
def initialize(name, *args) #:nodoc:
|
8
8
|
options = args.extract_options!
|
9
|
-
options.assert_valid_keys(:default)
|
9
|
+
options.assert_valid_keys(:default, :group_defaults)
|
10
10
|
|
11
11
|
@type = args.first ? args.first.to_sym : :boolean
|
12
12
|
|
13
13
|
# Create a column that will be responsible for typecasting
|
14
14
|
@column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == :any ? nil : @type.to_s)
|
15
|
+
|
16
|
+
@group_defaults = (options[:group_defaults] || {}).inject({}) do |defaults, (group, default)|
|
17
|
+
defaults[group.is_a?(Symbol) ? group.to_s : group] = type_cast(default)
|
18
|
+
defaults
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
22
|
# The name of the preference
|
@@ -21,8 +26,8 @@ module Preferences
|
|
21
26
|
|
22
27
|
# The default value to use for the preference in case none have been
|
23
28
|
# previously defined
|
24
|
-
def default_value
|
25
|
-
@column.default
|
29
|
+
def default_value(group = nil)
|
30
|
+
@group_defaults.include?(group) ? @group_defaults[group] : @column.default
|
26
31
|
end
|
27
32
|
|
28
33
|
# Determines whether column backing this preference stores numberic values
|
@@ -6,7 +6,6 @@ class ModelPreferenceTest < ActiveRecord::TestCase
|
|
6
6
|
|
7
7
|
def teardown
|
8
8
|
User.preference_definitions.clear
|
9
|
-
User.default_preferences.clear
|
10
9
|
end
|
11
10
|
end
|
12
11
|
|
@@ -15,10 +14,6 @@ class ModelWithoutPreferencesTest < ActiveRecord::TestCase
|
|
15
14
|
assert !Car.respond_to?(:preference_definitions)
|
16
15
|
end
|
17
16
|
|
18
|
-
def test_should_not_create_default_preferences
|
19
|
-
assert !Car.respond_to?(:default_preferences)
|
20
|
-
end
|
21
|
-
|
22
17
|
def test_should_not_create_stored_preferences_association
|
23
18
|
assert !Car.new.respond_to?(:stored_preferences)
|
24
19
|
end
|
@@ -39,10 +34,6 @@ class PreferencesAfterFirstBeingDefinedTest < ModelPreferenceTest
|
|
39
34
|
assert User.respond_to?(:preference_definitions)
|
40
35
|
end
|
41
36
|
|
42
|
-
def test_should_create_default_preferences
|
43
|
-
assert User.respond_to?(:default_preferences)
|
44
|
-
end
|
45
|
-
|
46
37
|
def test_should_create_preference_scopes
|
47
38
|
assert User.respond_to?(:with_preferences)
|
48
39
|
assert User.respond_to?(:without_preferences)
|
@@ -136,10 +127,6 @@ class PreferencesAfterBeingDefinedTest < ModelPreferenceTest
|
|
136
127
|
def test_should_include_new_definitions_in_preference_definitions
|
137
128
|
assert_equal e = {'notifications' => @definition}, User.preference_definitions
|
138
129
|
end
|
139
|
-
|
140
|
-
def test_should_include_default_value_in_default_preferences
|
141
|
-
assert_equal e = {'notifications' => nil}, User.default_preferences
|
142
|
-
end
|
143
130
|
end
|
144
131
|
|
145
132
|
class PreferencesByDefaultTest < ModelPreferenceTest
|
@@ -156,10 +143,6 @@ class PreferencesByDefaultTest < ModelPreferenceTest
|
|
156
143
|
assert_nil @definition.default_value
|
157
144
|
end
|
158
145
|
|
159
|
-
def test_should_include_in_default_preferences
|
160
|
-
assert_equal e = {'notifications' => nil}, User.default_preferences
|
161
|
-
end
|
162
|
-
|
163
146
|
def test_should_only_have_default_preferences
|
164
147
|
assert_equal e = {'notifications' => nil}, @user.preferences
|
165
148
|
end
|
@@ -203,10 +186,6 @@ class PreferencesWithCustomTypeTest < ModelPreferenceTest
|
|
203
186
|
assert_nil @definition.default_value
|
204
187
|
end
|
205
188
|
|
206
|
-
def test_should_include_in_default_preferences
|
207
|
-
assert_equal e = {'vehicle_id' => nil}, User.default_preferences
|
208
|
-
end
|
209
|
-
|
210
189
|
def test_should_only_have_default_preferences
|
211
190
|
assert_equal e = {'vehicle_id' => nil}, @user.preferences
|
212
191
|
end
|
@@ -226,10 +205,6 @@ class PreferencesWithCustomDefaultTest < ModelPreferenceTest
|
|
226
205
|
assert_equal 'red', @definition.default_value
|
227
206
|
end
|
228
207
|
|
229
|
-
def test_should_include_in_default_preferences
|
230
|
-
assert_equal e = {'color' => 'red'}, User.default_preferences
|
231
|
-
end
|
232
|
-
|
233
208
|
def test_should_only_have_default_preferences
|
234
209
|
assert_equal e = {'color' => 'red'}, @user.preferences
|
235
210
|
end
|
@@ -242,10 +217,6 @@ class PreferencesWithMultipleDefinitionsTest < ModelPreferenceTest
|
|
242
217
|
@user = new_user
|
243
218
|
end
|
244
219
|
|
245
|
-
def test_should_include_all_in_default_preferences
|
246
|
-
assert_equal e = {'notifications' => true, 'color' => 'red'}, User.default_preferences
|
247
|
-
end
|
248
|
-
|
249
220
|
def test_should_only_have_default_preferences
|
250
221
|
assert_equal e = {'notifications' => true, 'color' => 'red'}, @user.preferences
|
251
222
|
end
|
@@ -277,6 +248,11 @@ class PreferencesReaderTest < ModelPreferenceTest
|
|
277
248
|
assert_equal true, @user.preferred(:notifications)
|
278
249
|
end
|
279
250
|
|
251
|
+
def test_should_use_group_default_value_if_not_stored
|
252
|
+
User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'}
|
253
|
+
assert_equal 'English', @user.preferred(:language)
|
254
|
+
end
|
255
|
+
|
280
256
|
def test_should_use_stored_value_if_stored
|
281
257
|
create_preference(:owner => @user, :name => 'notifications', :value => false)
|
282
258
|
assert_equal false, @user.preferred(:notifications)
|
@@ -320,10 +296,15 @@ class PreferencesGroupReaderTest < ModelPreferenceTest
|
|
320
296
|
@user = create_user
|
321
297
|
end
|
322
298
|
|
323
|
-
def
|
299
|
+
def test_should_use_default_value_if_not_stored
|
324
300
|
assert_equal true, @user.preferred(:notifications, :chat)
|
325
301
|
end
|
326
302
|
|
303
|
+
def test_should_use_group_default_value_if_not_stored
|
304
|
+
User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'}
|
305
|
+
assert_equal 'Latin', @user.preferred(:language, :chat)
|
306
|
+
end
|
307
|
+
|
327
308
|
def test_should_use_stored_value_if_stored
|
328
309
|
create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
|
329
310
|
assert_equal false, @user.preferred(:notifications, :chat)
|
@@ -956,7 +937,7 @@ end
|
|
956
937
|
class PreferencesLookupTest < ModelPreferenceTest
|
957
938
|
def setup
|
958
939
|
User.preference :notifications, :boolean, :default => true
|
959
|
-
User.preference :language, :string, :default => 'English'
|
940
|
+
User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'}
|
960
941
|
|
961
942
|
@user = create_user
|
962
943
|
end
|
@@ -982,9 +963,9 @@ class PreferencesLookupTest < ModelPreferenceTest
|
|
982
963
|
end
|
983
964
|
|
984
965
|
def test_should_use_unsaved_changes_over_stored_preferences
|
985
|
-
create_preference(:owner => @user, :name => 'notifications', :value =>
|
986
|
-
@user.write_preference(:notifications,
|
987
|
-
assert_equal e = {'notifications' =>
|
966
|
+
create_preference(:owner => @user, :name => 'notifications', :value => true)
|
967
|
+
@user.write_preference(:notifications, false)
|
968
|
+
assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences
|
988
969
|
end
|
989
970
|
|
990
971
|
def test_should_cache_results
|
@@ -1013,29 +994,29 @@ end
|
|
1013
994
|
class PreferencesGroupLookupTest < ModelPreferenceTest
|
1014
995
|
def setup
|
1015
996
|
User.preference :notifications, :boolean, :default => true
|
1016
|
-
User.preference :language, :string, :default => 'English'
|
997
|
+
User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'}
|
1017
998
|
|
1018
999
|
@user = create_user
|
1019
1000
|
end
|
1020
1001
|
|
1021
1002
|
def test_should_only_have_defaults_if_nothing_customized
|
1022
|
-
assert_equal e = {'notifications' => true, 'language' => '
|
1003
|
+
assert_equal e = {'notifications' => true, 'language' => 'Latin'}, @user.preferences(:chat)
|
1023
1004
|
end
|
1024
1005
|
|
1025
1006
|
def test_should_merge_defaults_with_unsaved_changes
|
1026
1007
|
@user.write_preference(:notifications, false, :chat)
|
1027
|
-
assert_equal e = {'notifications' => false, 'language' => '
|
1008
|
+
assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(:chat)
|
1028
1009
|
end
|
1029
1010
|
|
1030
1011
|
def test_should_merge_defaults_with_saved_changes
|
1031
1012
|
create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
|
1032
|
-
assert_equal e = {'notifications' => false, 'language' => '
|
1013
|
+
assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(:chat)
|
1033
1014
|
end
|
1034
1015
|
|
1035
1016
|
def test_should_merge_stored_preferences_with_unsaved_changes
|
1036
1017
|
create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
|
1037
|
-
@user.write_preference(:language, '
|
1038
|
-
assert_equal e = {'notifications' => false, 'language' => '
|
1018
|
+
@user.write_preference(:language, 'Spanish', :chat)
|
1019
|
+
assert_equal e = {'notifications' => false, 'language' => 'Spanish'}, @user.preferences(:chat)
|
1039
1020
|
end
|
1040
1021
|
|
1041
1022
|
def test_should_cache_results
|
@@ -1252,6 +1233,14 @@ class PreferencesWithScopeTest < ModelPreferenceTest
|
|
1252
1233
|
assert_equal [@user], User.with_preferences(:chat => {:language => 'English'})
|
1253
1234
|
end
|
1254
1235
|
|
1236
|
+
def test_should_find_with_customized_default_group_preference
|
1237
|
+
User.preference :country, :string, :default => 'US', :group_defaults => {:chat => 'UK'}
|
1238
|
+
@customized_user.preferred_country = 'US', :chat
|
1239
|
+
@customized_user.save!
|
1240
|
+
|
1241
|
+
assert_equal [@user], User.with_preferences(:chat => {:country => 'UK'})
|
1242
|
+
end
|
1243
|
+
|
1255
1244
|
def test_should_find_with_multiple_default_group_preferences
|
1256
1245
|
assert_equal [@user], User.with_preferences(:chat => {:notifications => nil, :language => 'English'})
|
1257
1246
|
end
|
@@ -1328,6 +1317,14 @@ class PreferencesWithoutScopeTest < ModelPreferenceTest
|
|
1328
1317
|
assert_equal [@user], User.without_preferences(:chat => {:language => 'Latin'})
|
1329
1318
|
end
|
1330
1319
|
|
1320
|
+
def test_should_find_with_customized_default_group_preference
|
1321
|
+
User.preference :country, :string, :default => 'US', :group_defaults => {:chat => 'UK'}
|
1322
|
+
@customized_user.preferred_country = 'US', :chat
|
1323
|
+
@customized_user.save!
|
1324
|
+
|
1325
|
+
assert_equal [@user], User.without_preferences(:chat => {:country => 'US'})
|
1326
|
+
end
|
1327
|
+
|
1331
1328
|
def test_should_find_with_multiple_default_group_preferences
|
1332
1329
|
assert_equal [@user], User.without_preferences(:chat => {:language => 'Latin', :notifications => false})
|
1333
1330
|
end
|
@@ -42,6 +42,24 @@ class PreferenceDefinitionWithDefaultValueTest < ActiveSupport::TestCase
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
class PreferenceDefinitionWithGroupDefaultsTest < ActiveSupport::TestCase
|
46
|
+
def setup
|
47
|
+
@definition = Preferences::PreferenceDefinition.new(:notifications, :boolean, :default => 1, :group_defaults => {:chat => 0})
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_should_use_default_for_default_group
|
51
|
+
assert_equal true, @definition.default_value
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_should_use_default_for_unknown_group
|
55
|
+
assert_equal true, @definition.default_value('email')
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_should_use_group_default_for_known_group
|
59
|
+
assert_equal false, @definition.default_value('chat')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
45
63
|
class PreferenceDefinitionWithStringifiedTypeTest < ActiveSupport::TestCase
|
46
64
|
def setup
|
47
65
|
@definition = Preferences::PreferenceDefinition.new(:notifications, 'any')
|
@@ -157,7 +157,6 @@ class PreferenceAfterBeingCreatedTest < ActiveSupport::TestCase
|
|
157
157
|
|
158
158
|
def teardown
|
159
159
|
User.preference_definitions.delete('notifications')
|
160
|
-
User.default_preferences.delete('notifications')
|
161
160
|
end
|
162
161
|
end
|
163
162
|
|
@@ -210,7 +209,6 @@ class PreferenceWithBooleanTypeTest < ActiveSupport::TestCase
|
|
210
209
|
|
211
210
|
def teardown
|
212
211
|
User.preference_definitions.delete('notifications')
|
213
|
-
User.default_preferences.delete('notifications')
|
214
212
|
end
|
215
213
|
end
|
216
214
|
|