aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-02-01 14:25:33 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2011-02-01 14:25:47 -0800
commita0fac7192241f3242af410ca16e6dd43b933c98e (patch)
tree2bc99ef839dfc2fda1328b8eabc4c5d4c2306f7a
parentebe485fd8ec80a1a9b86516bc6f74bc5bbba3476 (diff)
downloadrails-a0fac7192241f3242af410ca16e6dd43b933c98e.tar.gz
rails-a0fac7192241f3242af410ca16e6dd43b933c98e.tar.bz2
rails-a0fac7192241f3242af410ca16e6dd43b933c98e.zip
store the serialized column values in the @attributes hash
-rw-r--r--activerecord/lib/active_record/attribute_methods/write.rb3
-rw-r--r--activerecord/lib/active_record/base.rb21
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb6
-rw-r--r--activerecord/test/cases/base_test.rb25
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