Skip to content

Commit

Permalink
Fix preference definition types not being used to typecast values
Browse files Browse the repository at this point in the history
  • Loading branch information
obrie committed Mar 7, 2010
1 parent 32dff7c commit eaa4f47
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rdoc
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,6 @@
== master == master


* Fix preference definition types not being used to typecast values
* No longer allow both group and non-group preferences to be looked up at once (except for named scopes) * No longer allow both group and non-group preferences to be looked up at once (except for named scopes)
* Add support for using Symbols to reference groups * Add support for using Symbols to reference groups
* Fix #reload not causing unsaved preferences to get reset * Fix #reload not causing unsaved preferences to get reset
Expand Down
11 changes: 8 additions & 3 deletions lib/preferences.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ def preferred(name, group = nil)
preferences_group(group)[name] = value preferences_group(group)[name] = value
end end


definition = preference_definitions[name]
value = definition.type_cast(value) unless value.nil?
value value
end end
alias_method :prefers, :preferred alias_method :prefers, :preferred
Expand Down Expand Up @@ -372,6 +374,7 @@ def write_preference(name, value, group = nil)
preferences_changed(group)[name] = old if preference_value_changed?(name, old, value) preferences_changed(group)[name] = old if preference_value_changed?(name, old, value)
end end


value = convert_number_column_value(value) if preference_definitions[name].number?
preferences_group(group)[name] = value preferences_group(group)[name] = value


value value
Expand Down Expand Up @@ -427,9 +430,11 @@ def preferences_changed(group = nil)
# equality. # equality.
def preference_value_changed?(name, old, value) def preference_value_changed?(name, old, value)
definition = preference_definitions[name] definition = preference_definitions[name]
if definition.type == :integer && old.nil? if definition.type == :integer && (old.nil? || old == 0)
# NULL gets stored in database for blank (i.e. '') values. Hence we # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values.
# don't record it as a change if the value changes from nil to ''. # Hence we don't record it as a change if the value changes from nil to ''.
# If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
# be typecast back to 0 (''.to_i => 0)
value = nil if value.blank? value = nil if value.blank?
else else
value = definition.type_cast(value) value = definition.type_cast(value)
Expand Down
5 changes: 5 additions & 0 deletions lib/preferences/preference_definition.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ def default_value
@column.default @column.default
end end


# Determines whether column backing this preference stores numberic values
def number?
@column.number?
end

# Typecasts the value based on the type of preference that was defined. # Typecasts the value based on the type of preference that was defined.
# This uses ActiveRecord's typecast functionality so the same rules for # This uses ActiveRecord's typecast functionality so the same rules for
# typecasting a model's columns apply here. # typecasting a model's columns apply here.
Expand Down
15 changes: 15 additions & 0 deletions test/functional/preferences_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ def test_should_use_stored_value_if_stored
assert_equal false, @user.preferred(:notifications) assert_equal false, @user.preferred(:notifications)
end end


def test_should_type_cast_based_on_preference_definition
@user.write_preference(:notifications, 'false')
assert_equal false, @user.preferred(:notifications)
end

def test_should_cache_stored_values def test_should_cache_stored_values
create_preference(:owner => @user, :name => 'notifications', :value => false) create_preference(:owner => @user, :name => 'notifications', :value => false)
assert_queries(1) { @user.preferred(:notifications) } assert_queries(1) { @user.preferred(:notifications) }
Expand Down Expand Up @@ -476,6 +481,16 @@ def test_should_not_create_stored_integer_preference_if_typecast_not_changed
assert_equal 0, @user.stored_preferences.count assert_equal 0, @user.stored_preferences.count
end end


def test_should_create_stored_integer_preference_if_typecast_changed
User.preference :age, :integer, :default => 0

@user.write_preference(:age, '')
@user.save!

assert_nil @user.preferred(:age)
assert_equal 1, @user.stored_preferences.count
end

def test_should_create_stored_preference_if_value_changed def test_should_create_stored_preference_if_value_changed
@user.write_preference(:notifications, false) @user.write_preference(:notifications, false)
@user.save! @user.save!
Expand Down
16 changes: 16 additions & 0 deletions test/unit/preference_definition_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ def test_use_custom_type
assert_equal :any, @definition.type assert_equal :any, @definition.type
end end


def test_should_not_be_number
assert !@definition.number?
end

def test_should_not_type_cast def test_should_not_type_cast
assert_equal nil, @definition.type_cast(nil) assert_equal nil, @definition.type_cast(nil)
assert_equal 0, @definition.type_cast(0) assert_equal 0, @definition.type_cast(0)
Expand Down Expand Up @@ -97,6 +101,10 @@ def setup
@definition = Preferences::PreferenceDefinition.new(:notifications) @definition = Preferences::PreferenceDefinition.new(:notifications)
end end


def test_should_not_be_number
assert !@definition.number?
end

def test_should_not_type_cast_if_value_is_nil def test_should_not_type_cast_if_value_is_nil
assert_equal nil, @definition.type_cast(nil) assert_equal nil, @definition.type_cast(nil)
end end
Expand Down Expand Up @@ -143,6 +151,10 @@ def setup
@definition = Preferences::PreferenceDefinition.new(:notifications, :integer) @definition = Preferences::PreferenceDefinition.new(:notifications, :integer)
end end


def test_should_be_number
assert @definition.number?
end

def test_should_type_cast_true_to_integer def test_should_type_cast_true_to_integer
assert_equal 1, @definition.type_cast(true) assert_equal 1, @definition.type_cast(true)
end end
Expand Down Expand Up @@ -173,6 +185,10 @@ def setup
@definition = Preferences::PreferenceDefinition.new(:notifications, :string) @definition = Preferences::PreferenceDefinition.new(:notifications, :string)
end end


def test_should_not_be_number
assert !@definition.number?
end

def test_should_type_cast_integers_to_strings def test_should_type_cast_integers_to_strings
assert_equal '1', @definition.type_cast('1') assert_equal '1', @definition.type_cast('1')
end end
Expand Down

0 comments on commit eaa4f47

Please sign in to comment.