aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md16
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb8
-rw-r--r--activerecord/lib/active_record/attribute_methods/write.rb36
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/column.rb9
-rw-r--r--activerecord/lib/active_record/scoping.rb4
-rw-r--r--activerecord/lib/active_record/scoping/named.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb11
-rw-r--r--activerecord/test/cases/scoping/named_scoping_test.rb7
-rw-r--r--activerecord/test/cases/serialized_attribute_test.rb16
-rw-r--r--activerecord/test/fixtures/ratings.yml10
-rw-r--r--activerecord/test/models/comment.rb1
-rw-r--r--activerecord/test/models/rating.rb4
-rw-r--r--activerecord/test/schema/schema.rb2
14 files changed, 64 insertions, 74 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index a37f1ad540..1c85197ec7 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,20 +1,14 @@
+* Fixed serialized fields returning serialized data after being updated with
+ `update_column`.
+
+ *Simon Hørup Eskildsen*
+
* Fixed polymorphic eager loading when using a String as foreign key.
Fixes #14734.
*Lauro Caetano*
-* Changed scoped blocks to be executed with `instance_eval`
-
- Named scopes (i.e. using STI) were previously cached according to
- base class so scoped queries made by classes with a common ancestor would
- leak. Changed the way scope blocks were called so inheritance rules are
- followed during the call and scopes are cached correctly.
-
- Fixes #13466.
-
- *Jefferson Lai*
-
* Change belongs_to touch to be consistent with timestamp updates
If a model is set up with a belongs_to: touch relatinoship the parent
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index c3466153d6..53a9c874bf 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -142,6 +142,14 @@ module ActiveRecord
end
end
+ def raw_type_cast_attribute_for_write(column, value)
+ if column && coder = self.class.serialized_attributes[column.name]
+ Attribute.new(coder, value, :serialized)
+ else
+ super
+ end
+ end
+
def _field_changed?(attr, old, value)
if self.class.serialized_attributes.include?(attr)
old != value
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index c853fc0917..56441d7324 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -55,6 +55,27 @@ module ActiveRecord
# specified +value+. Empty strings for fixnum and float columns are
# turned into +nil+.
def write_attribute(attr_name, value)
+ write_attribute_with_type_cast(attr_name, value, :type_cast_attribute_for_write)
+ end
+
+ def raw_write_attribute(attr_name, value)
+ write_attribute_with_type_cast(attr_name, value, :raw_type_cast_attribute_for_write)
+ end
+
+ private
+ # Handle *= for method_missing.
+ def attribute=(attribute_name, value)
+ write_attribute(attribute_name, value)
+ end
+
+ def type_cast_attribute_for_write(column, value)
+ return value unless column
+
+ column.type_cast_for_write value
+ end
+ alias_method :raw_type_cast_attribute_for_write, :type_cast_attribute_for_write
+
+ def write_attribute_with_type_cast(attr_name, value, type_cast_method)
attr_name = attr_name.to_s
attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
@attributes_cache.delete(attr_name)
@@ -67,24 +88,11 @@ module ActiveRecord
end
if column || @attributes.has_key?(attr_name)
- @attributes[attr_name] = type_cast_attribute_for_write(column, value)
+ @attributes[attr_name] = send(type_cast_method, column, value)
else
raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{attr_name}'"
end
end
- alias_method :raw_write_attribute, :write_attribute
-
- private
- # Handle *= for method_missing.
- def attribute=(attribute_name, value)
- write_attribute(attribute_name, value)
- end
-
- def type_cast_attribute_for_write(column, value)
- return value unless column
-
- column.type_cast_for_write value
- end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 8beb869ce2..aa8a91ed39 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -262,7 +262,7 @@ module ActiveRecord
@connection.insert_id
end
- module Fields
+ module Fields # :nodoc:
class DateTime < Type::DateTime
def cast_value(value)
if Mysql::Time === value
@@ -359,7 +359,7 @@ module ActiveRecord
end
end
- def execute_and_free(sql, name = nil)
+ def execute_and_free(sql, name = nil) # :nodoc:
result = execute(sql, name)
ret = yield result
result.free
@@ -372,7 +372,7 @@ module ActiveRecord
end
alias :create :insert_sql
- def exec_delete(sql, name, binds)
+ def exec_delete(sql, name, binds) # :nodoc:
affected_rows = 0
exec_query(sql, name, binds) do |n|
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
index 95f52312a5..80c79642f3 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
@@ -6,16 +6,15 @@ module ActiveRecord
class PostgreSQLColumn < Column #:nodoc:
attr_accessor :array
- def initialize(name, default, oid_type, sql_type = nil, null = true)
- @oid_type = oid_type
+ def initialize(name, default, cast_type, sql_type = nil, null = true)
default_value = self.class.extract_value_from_default(default)
if sql_type =~ /\[\]$/
@array = true
- super(name, default_value, oid_type, sql_type[0..sql_type.length - 3], null)
+ super(name, default_value, cast_type, sql_type[0..sql_type.length - 3], null)
else
@array = false
- super(name, default_value, oid_type, sql_type, null)
+ super(name, default_value, cast_type, sql_type, null)
end
@default_function = default if has_default_function?(default_value, default)
@@ -105,7 +104,7 @@ module ActiveRecord
end
def accessor
- @oid_type.accessor
+ cast_type.accessor
end
private
diff --git a/activerecord/lib/active_record/scoping.rb b/activerecord/lib/active_record/scoping.rb
index fca4f1c9d3..3e43591672 100644
--- a/activerecord/lib/active_record/scoping.rb
+++ b/activerecord/lib/active_record/scoping.rb
@@ -11,11 +11,11 @@ module ActiveRecord
module ClassMethods
def current_scope #:nodoc:
- ScopeRegistry.value_for(:current_scope, self.to_s)
+ ScopeRegistry.value_for(:current_scope, base_class.to_s)
end
def current_scope=(scope) #:nodoc:
- ScopeRegistry.set_value_for(:current_scope, self.to_s, scope)
+ ScopeRegistry.set_value_for(:current_scope, base_class.to_s, scope)
end
end
diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb
index 826b710e92..49cadb66d0 100644
--- a/activerecord/lib/active_record/scoping/named.rb
+++ b/activerecord/lib/active_record/scoping/named.rb
@@ -148,13 +148,9 @@ module ActiveRecord
extension = Module.new(&block) if block
singleton_class.send(:define_method, name) do |*args|
- if body.respond_to?(:to_proc)
- scope = all.scoping { instance_exec(*args, &body) }
- else
- # Body is given as an object instead of a block, so invoke call()
- scope = all.scoping { body.call(*args) }
- end
+ scope = all.scoping { body.call(*args) }
scope = scope.extending(extension) if extension
+
scope || all
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index c20030ca64..34c2008ab4 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -89,16 +89,7 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
end
def test_type_cast_array
- data = '{1,2,3}'
- oid_type = @column.instance_variable_get('@oid_type').subtype
- # we are getting the instance variable in this test, but in the
- # normal use of string_to_array, it's called from the OID::Array
- # class and will have the OID instance that will provide the type
- # casting
- array = @column.class.string_to_array data, oid_type
- assert_equal(['1', '2', '3'], array)
- assert_equal(['1', '2', '3'], @column.type_cast(data))
-
+ assert_equal(['1', '2', '3'], @column.type_cast('{1,2,3}'))
assert_equal([], @column.type_cast('{}'))
assert_equal([nil], @column.type_cast('{NULL}'))
end
diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb
index bfde9448f3..59ec2dd6a4 100644
--- a/activerecord/test/cases/scoping/named_scoping_test.rb
+++ b/activerecord/test/cases/scoping/named_scoping_test.rb
@@ -2,13 +2,12 @@ require "cases/helper"
require 'models/post'
require 'models/topic'
require 'models/comment'
-require 'models/rating'
require 'models/reply'
require 'models/author'
require 'models/developer'
class NamedScopingTest < ActiveRecord::TestCase
- fixtures :posts, :authors, :topics, :comments, :author_addresses, :ratings
+ fixtures :posts, :authors, :topics, :comments, :author_addresses
def test_implements_enumerable
assert !Topic.all.empty?
@@ -116,10 +115,6 @@ class NamedScopingTest < ActiveRecord::TestCase
assert_equal 1,SpecialPost.containing_the_letter_a.count
end
- def test_scope_subquery_with_STI
- assert_nothing_raised { VerySpecialComment.special_parent(SpecialRating.first).count }
- end
-
def test_has_many_through_associations_have_access_to_scopes
assert_not_equal Comment.containing_the_letter_e, authors(:david).comments
assert !Comment.containing_the_letter_e.empty?
diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb
index 5609cf310c..c8f9d7cf87 100644
--- a/activerecord/test/cases/serialized_attribute_test.rb
+++ b/activerecord/test/cases/serialized_attribute_test.rb
@@ -244,4 +244,20 @@ class SerializedAttributeTest < ActiveRecord::TestCase
type = Topic.column_types["content"]
assert !type.instance_variable_get("@column").is_a?(ActiveRecord::AttributeMethods::Serialization::Type)
end
+
+ def test_serialized_column_should_unserialize_after_update_column
+ t = Topic.create(content: "first")
+ assert_equal("first", t.content)
+
+ t.update_column(:content, Topic.serialized_attributes["content"].dump("second"))
+ assert_equal("second", t.content)
+ end
+
+ def test_serialized_column_should_unserialize_after_update_attribute
+ t = Topic.create(content: "first")
+ assert_equal("first", t.content)
+
+ t.update_attribute(:content, "second")
+ assert_equal("second", t.content)
+ end
end
diff --git a/activerecord/test/fixtures/ratings.yml b/activerecord/test/fixtures/ratings.yml
index 2b45c5080e..34e208efa3 100644
--- a/activerecord/test/fixtures/ratings.yml
+++ b/activerecord/test/fixtures/ratings.yml
@@ -2,23 +2,13 @@ normal_comment_rating:
id: 1
comment_id: 8
value: 1
- type: Rating
special_comment_rating:
id: 2
comment_id: 6
value: 1
- type: Rating
sub_special_comment_rating:
id: 3
comment_id: 12
value: 1
- type: Rating
-
-special_rating:
- id: 4
- comment_id: 10
- value: 1
- type: SpecialRating
- special_comment_id: 3
diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb
index d5a1231060..15970758db 100644
--- a/activerecord/test/models/comment.rb
+++ b/activerecord/test/models/comment.rb
@@ -42,7 +42,6 @@ class SubSpecialComment < SpecialComment
end
class VerySpecialComment < Comment
- scope :special_parent, ->(special_rating) { where parent_id: special_rating.special_comment.id }
end
class CommentThatAutomaticallyAltersPostBody < Comment
diff --git a/activerecord/test/models/rating.rb b/activerecord/test/models/rating.rb
index 5409230c2e..25a52c4ad7 100644
--- a/activerecord/test/models/rating.rb
+++ b/activerecord/test/models/rating.rb
@@ -2,7 +2,3 @@ class Rating < ActiveRecord::Base
belongs_to :comment
has_many :taggings, :as => :taggable
end
-
-class SpecialRating < Rating
- belongs_to :special_comment
-end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 67ba358843..8c52ad2724 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -598,9 +598,7 @@ ActiveRecord::Schema.define do
create_table :ratings, force: true do |t|
t.integer :comment_id
- t.integer :special_comment_id
t.integer :value
- t.string :type
end
create_table :readers, force: true do |t|