diff options
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/write.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/active_record/base.rb | 21 | ||||
-rw-r--r-- | activerecord/lib/active_record/validations/uniqueness.rb | 6 | ||||
-rw-r--r-- | activerecord/test/cases/base_test.rb | 25 |
4 files changed, 41 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb index 6a593a7e0e..5eba94ec66 100644 --- a/activerecord/lib/active_record/attribute_methods/write.rb +++ b/activerecord/lib/active_record/attribute_methods/write.rb @@ -23,7 +23,8 @@ module ActiveRecord if (column = column_for_attribute(attr_name)) && column.number? @attributes[attr_name] = convert_number_column_value(value) else - @attributes[attr_name] = value + coder = self.class.serialized_attributes[attr_name] + @attributes[attr_name] = coder ? coder.dump(value) : value end end diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 5310b55a92..6b82b827b0 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1739,18 +1739,25 @@ MSG # Returns a copy of the attributes hash where all the values have been safely quoted for use in # an Arel insert/update method. def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys) - attrs = {} + attrs = {} + klass = self.class + arel_table = klass.arel_table + attribute_names.each do |name| if (column = column_for_attribute(name)) && (include_primary_key || !column.primary) if include_readonly_attributes || (!include_readonly_attributes && !self.class.readonly_attributes.include?(name)) - value = read_attribute(name) - coder = self.class.serialized_attributes[name] - if !value.nil? && coder - value = coder.dump value - end - attrs[self.class.arel_table[name]] = value + value = if klass.serialized_attributes[name] + @attributes[name] + else + # FIXME: we need @attributes to be used consistently. + # If the values stored in @attributes were already type + # casted, this code could be simplified + read_attribute(name) + end + + attrs[arel_table[name]] = value end end end diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index a96796f9ff..76110b73e4 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -15,12 +15,6 @@ module ActiveRecord def validate_each(record, attribute, value) finder_class = find_finder_class_for(record) - coder = record.class.serialized_attributes[attribute.to_s] - - if value && coder - value = coder.dump value - end - sql, params = mount_sql_and_params(finder_class, record.class.quoted_table_name, attribute, value) relation = finder_class.unscoped.where(sql, *params) diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 7c677d55ca..5cbc52732b 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1037,6 +1037,31 @@ class BasicsTest < ActiveRecord::TestCase assert topic.save topic = topic.reload assert_equal [s].pack('m'), topic.content + ensure + Topic.serialize(:content) + end + + def test_serialize_with_bcrypt_coder + crypt_coder = Class.new { + def load(thing) + return unless thing + BCrypt::Password.new thing + end + + def dump(thing) + BCrypt::Password.create(thing).to_s + end + }.new + + Topic.serialize(:content, crypt_coder) + password = 'password' + topic = Topic.new(:content => password) + assert topic.save + topic = topic.reload + assert_kind_of BCrypt::Password, topic.content + assert_equal(true, topic.content == password, 'password should equal') + ensure + Topic.serialize(:content) end def test_quote |