activerecord 3.1.9 → 3.2.12
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.
- checksums.yaml +6 -6
- data/CHANGELOG.md +317 -336
- data/README.rdoc +3 -3
- data/examples/performance.rb +20 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +3 -6
- data/lib/active_record/associations/association.rb +3 -42
- data/lib/active_record/associations/association_scope.rb +3 -15
- data/lib/active_record/associations/builder/association.rb +6 -4
- data/lib/active_record/associations/builder/belongs_to.rb +3 -3
- data/lib/active_record/associations/builder/collection_association.rb +2 -2
- data/lib/active_record/associations/builder/has_many.rb +4 -4
- data/lib/active_record/associations/builder/has_one.rb +5 -6
- data/lib/active_record/associations/builder/singular_association.rb +3 -16
- data/lib/active_record/associations/collection_association.rb +64 -31
- data/lib/active_record/associations/collection_proxy.rb +2 -37
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -0
- data/lib/active_record/associations/has_many_association.rb +5 -1
- data/lib/active_record/associations/has_many_through_association.rb +28 -9
- data/lib/active_record/associations/has_one_association.rb +15 -13
- data/lib/active_record/associations/join_dependency.rb +2 -2
- data/lib/active_record/associations/preloader.rb +14 -10
- data/lib/active_record/associations/through_association.rb +7 -3
- data/lib/active_record/associations.rb +92 -76
- data/lib/active_record/attribute_assignment.rb +221 -0
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
- data/lib/active_record/attribute_methods/dirty.rb +21 -11
- data/lib/active_record/attribute_methods/primary_key.rb +62 -25
- data/lib/active_record/attribute_methods/read.rb +73 -83
- data/lib/active_record/attribute_methods/serialization.rb +102 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +23 -17
- data/lib/active_record/attribute_methods/write.rb +31 -6
- data/lib/active_record/attribute_methods.rb +231 -30
- data/lib/active_record/autosave_association.rb +43 -22
- data/lib/active_record/base.rb +227 -1708
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +150 -148
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +85 -29
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +6 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +10 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +37 -26
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +48 -19
- data/lib/active_record/connection_adapters/abstract_adapter.rb +77 -42
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +674 -0
- data/lib/active_record/connection_adapters/column.rb +37 -11
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +129 -581
- data/lib/active_record/connection_adapters/mysql_adapter.rb +137 -696
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +184 -86
- data/lib/active_record/connection_adapters/schema_cache.rb +50 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -6
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +55 -32
- data/lib/active_record/counter_cache.rb +9 -4
- data/lib/active_record/dynamic_finder_match.rb +12 -0
- data/lib/active_record/dynamic_matchers.rb +84 -0
- data/lib/active_record/errors.rb +11 -1
- data/lib/active_record/explain.rb +85 -0
- data/lib/active_record/explain_subscriber.rb +25 -0
- data/lib/active_record/fixtures/file.rb +65 -0
- data/lib/active_record/fixtures.rb +56 -85
- data/lib/active_record/identity_map.rb +3 -4
- data/lib/active_record/inheritance.rb +174 -0
- data/lib/active_record/integration.rb +49 -0
- data/lib/active_record/locking/optimistic.rb +30 -25
- data/lib/active_record/locking/pessimistic.rb +23 -1
- data/lib/active_record/log_subscriber.rb +3 -3
- data/lib/active_record/migration/command_recorder.rb +8 -8
- data/lib/active_record/migration.rb +68 -35
- data/lib/active_record/model_schema.rb +366 -0
- data/lib/active_record/nested_attributes.rb +3 -2
- data/lib/active_record/persistence.rb +57 -11
- data/lib/active_record/querying.rb +58 -0
- data/lib/active_record/railtie.rb +31 -29
- data/lib/active_record/railties/controller_runtime.rb +3 -1
- data/lib/active_record/railties/databases.rake +191 -110
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +26 -0
- data/lib/active_record/reflection.rb +7 -15
- data/lib/active_record/relation/batches.rb +5 -2
- data/lib/active_record/relation/calculations.rb +47 -15
- data/lib/active_record/relation/delegation.rb +49 -0
- data/lib/active_record/relation/finder_methods.rb +9 -7
- data/lib/active_record/relation/predicate_builder.rb +18 -7
- data/lib/active_record/relation/query_methods.rb +75 -9
- data/lib/active_record/relation/spawn_methods.rb +11 -2
- data/lib/active_record/relation.rb +78 -32
- data/lib/active_record/result.rb +1 -1
- data/lib/active_record/sanitization.rb +194 -0
- data/lib/active_record/schema_dumper.rb +12 -5
- data/lib/active_record/scoping/default.rb +142 -0
- data/lib/active_record/scoping/named.rb +202 -0
- data/lib/active_record/scoping.rb +152 -0
- data/lib/active_record/serialization.rb +1 -43
- data/lib/active_record/serializers/xml_serializer.rb +4 -45
- data/lib/active_record/session_store.rb +17 -15
- data/lib/active_record/store.rb +52 -0
- data/lib/active_record/test_case.rb +11 -7
- data/lib/active_record/timestamp.rb +17 -3
- data/lib/active_record/transactions.rb +27 -6
- data/lib/active_record/translation.rb +22 -0
- data/lib/active_record/validations/associated.rb +5 -4
- data/lib/active_record/validations/uniqueness.rb +7 -7
- data/lib/active_record/validations.rb +1 -1
- data/lib/active_record/version.rb +2 -2
- data/lib/active_record.rb +38 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb +12 -3
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -1
- data/lib/rails/generators/active_record/model/templates/migration.rb +3 -5
- data/lib/rails/generators/active_record/model/templates/model.rb +5 -0
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +1 -5
- metadata +30 -10
- data/lib/active_record/named_scope.rb +0 -200
|
@@ -8,7 +8,9 @@ module ActiveRecord
|
|
|
8
8
|
|
|
9
9
|
def initialize(owner, reflection)
|
|
10
10
|
super
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
@through_records = {}
|
|
13
|
+
@through_association = nil
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
# Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been
|
|
@@ -36,6 +38,20 @@ module ActiveRecord
|
|
|
36
38
|
super
|
|
37
39
|
end
|
|
38
40
|
|
|
41
|
+
def concat_records(records)
|
|
42
|
+
ensure_not_nested
|
|
43
|
+
|
|
44
|
+
records = super
|
|
45
|
+
|
|
46
|
+
if owner.new_record? && records
|
|
47
|
+
records.flatten.each do |record|
|
|
48
|
+
build_through_record(record)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
records
|
|
53
|
+
end
|
|
54
|
+
|
|
39
55
|
def insert_record(record, validate = true, raise = false)
|
|
40
56
|
ensure_not_nested
|
|
41
57
|
|
|
@@ -59,7 +75,7 @@ module ActiveRecord
|
|
|
59
75
|
private
|
|
60
76
|
|
|
61
77
|
def through_association
|
|
62
|
-
owner.association(through_reflection.name)
|
|
78
|
+
@through_association ||= owner.association(through_reflection.name)
|
|
63
79
|
end
|
|
64
80
|
|
|
65
81
|
# We temporarily cache through record that has been build, because if we build a
|
|
@@ -71,7 +87,9 @@ module ActiveRecord
|
|
|
71
87
|
# association
|
|
72
88
|
def build_through_record(record)
|
|
73
89
|
@through_records[record.object_id] ||= begin
|
|
74
|
-
|
|
90
|
+
ensure_mutable
|
|
91
|
+
|
|
92
|
+
through_record = through_association.build
|
|
75
93
|
through_record.send("#{source_reflection.name}=", record)
|
|
76
94
|
through_record
|
|
77
95
|
end
|
|
@@ -122,8 +140,7 @@ module ActiveRecord
|
|
|
122
140
|
def delete_records(records, method)
|
|
123
141
|
ensure_not_nested
|
|
124
142
|
|
|
125
|
-
|
|
126
|
-
scope = through.scoped.where(construct_join_attributes(*records))
|
|
143
|
+
scope = through_association.scoped.where(construct_join_attributes(*records))
|
|
127
144
|
|
|
128
145
|
case method
|
|
129
146
|
when :destroy
|
|
@@ -134,7 +151,7 @@ module ActiveRecord
|
|
|
134
151
|
count = scope.delete_all
|
|
135
152
|
end
|
|
136
153
|
|
|
137
|
-
delete_through_records(
|
|
154
|
+
delete_through_records(records)
|
|
138
155
|
|
|
139
156
|
if through_reflection.macro == :has_many && update_through_counter?(method)
|
|
140
157
|
update_counter(-count, through_reflection)
|
|
@@ -149,14 +166,16 @@ module ActiveRecord
|
|
|
149
166
|
candidates.find_all { |c| c.attributes.slice(*attributes.keys) == attributes }
|
|
150
167
|
end
|
|
151
168
|
|
|
152
|
-
def delete_through_records(
|
|
169
|
+
def delete_through_records(records)
|
|
153
170
|
records.each do |record|
|
|
154
171
|
through_records = through_records_for(record)
|
|
155
172
|
|
|
156
173
|
if through_reflection.macro == :has_many
|
|
157
|
-
through_records.each { |r|
|
|
174
|
+
through_records.each { |r| through_association.target.delete(r) }
|
|
158
175
|
else
|
|
159
|
-
|
|
176
|
+
if through_records.include?(through_association.target)
|
|
177
|
+
through_association.target = nil
|
|
178
|
+
end
|
|
160
179
|
end
|
|
161
180
|
|
|
162
181
|
@through_records.delete(record.object_id)
|
|
@@ -8,19 +8,21 @@ module ActiveRecord
|
|
|
8
8
|
raise_on_type_mismatch(record) if record
|
|
9
9
|
load_target
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
# If target and record are nil, or target is equal to record,
|
|
12
|
+
# we don't need to have transaction.
|
|
13
|
+
if (target || record) && target != record
|
|
14
|
+
reflection.klass.transaction do
|
|
15
|
+
remove_target!(options[:dependent]) if target && !target.destroyed?
|
|
16
|
+
|
|
17
|
+
if record
|
|
18
|
+
set_owner_attributes(record)
|
|
19
|
+
set_inverse_instance(record)
|
|
20
|
+
|
|
21
|
+
if owner.persisted? && save && !record.save
|
|
22
|
+
nullify_owner_attributes(record)
|
|
23
|
+
set_owner_attributes(target) if target
|
|
24
|
+
raise RecordNotSaved, "Failed to save the new associated #{reflection.name}."
|
|
25
|
+
end
|
|
24
26
|
end
|
|
25
27
|
end
|
|
26
28
|
end
|
|
@@ -13,7 +13,7 @@ module ActiveRecord
|
|
|
13
13
|
@join_parts = [JoinBase.new(base)]
|
|
14
14
|
@associations = {}
|
|
15
15
|
@reflections = []
|
|
16
|
-
@alias_tracker = AliasTracker.new(joins)
|
|
16
|
+
@alias_tracker = AliasTracker.new(base.connection, joins)
|
|
17
17
|
@alias_tracker.aliased_name_for(base.table_name) # Updates the count for base.table_name to 1
|
|
18
18
|
build(associations)
|
|
19
19
|
end
|
|
@@ -184,7 +184,7 @@ module ActiveRecord
|
|
|
184
184
|
|
|
185
185
|
macro = join_part.reflection.macro
|
|
186
186
|
if macro == :has_one
|
|
187
|
-
return if record.association_cache.key?(join_part.reflection.name)
|
|
187
|
+
return record.association(join_part.reflection.name).target if record.association_cache.key?(join_part.reflection.name)
|
|
188
188
|
association = join_part.instantiate(row) unless row[join_part.aliased_primary_key].nil?
|
|
189
189
|
set_target_and_inverse(join_part, association, record)
|
|
190
190
|
else
|
|
@@ -30,17 +30,21 @@ module ActiveRecord
|
|
|
30
30
|
# option references an association's column), it will fallback to the table
|
|
31
31
|
# join strategy.
|
|
32
32
|
class Preloader #:nodoc:
|
|
33
|
-
|
|
34
|
-
autoload :SingularAssociation, 'active_record/associations/preloader/singular_association'
|
|
35
|
-
autoload :CollectionAssociation, 'active_record/associations/preloader/collection_association'
|
|
36
|
-
autoload :ThroughAssociation, 'active_record/associations/preloader/through_association'
|
|
33
|
+
extend ActiveSupport::Autoload
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
eager_autoload do
|
|
36
|
+
autoload :Association, 'active_record/associations/preloader/association'
|
|
37
|
+
autoload :SingularAssociation, 'active_record/associations/preloader/singular_association'
|
|
38
|
+
autoload :CollectionAssociation, 'active_record/associations/preloader/collection_association'
|
|
39
|
+
autoload :ThroughAssociation, 'active_record/associations/preloader/through_association'
|
|
40
|
+
|
|
41
|
+
autoload :HasMany, 'active_record/associations/preloader/has_many'
|
|
42
|
+
autoload :HasManyThrough, 'active_record/associations/preloader/has_many_through'
|
|
43
|
+
autoload :HasOne, 'active_record/associations/preloader/has_one'
|
|
44
|
+
autoload :HasOneThrough, 'active_record/associations/preloader/has_one_through'
|
|
45
|
+
autoload :HasAndBelongsToMany, 'active_record/associations/preloader/has_and_belongs_to_many'
|
|
46
|
+
autoload :BelongsTo, 'active_record/associations/preloader/belongs_to'
|
|
47
|
+
end
|
|
44
48
|
|
|
45
49
|
attr_reader :records, :associations, :options, :model
|
|
46
50
|
|
|
@@ -37,9 +37,7 @@ module ActiveRecord
|
|
|
37
37
|
# situation it is more natural for the user to just create or modify their join records
|
|
38
38
|
# directly as required.
|
|
39
39
|
def construct_join_attributes(*records)
|
|
40
|
-
|
|
41
|
-
raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
|
|
42
|
-
end
|
|
40
|
+
ensure_mutable
|
|
43
41
|
|
|
44
42
|
join_attributes = {
|
|
45
43
|
source_reflection.foreign_key =>
|
|
@@ -73,6 +71,12 @@ module ActiveRecord
|
|
|
73
71
|
!owner[through_reflection.foreign_key].nil?
|
|
74
72
|
end
|
|
75
73
|
|
|
74
|
+
def ensure_mutable
|
|
75
|
+
if source_reflection.macro != :belongs_to
|
|
76
|
+
raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
76
80
|
def ensure_not_nested
|
|
77
81
|
if reflection.nested?
|
|
78
82
|
raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection)
|