activerecord 3.2.22.4 → 4.0.13

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2799 -617
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +23 -32
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +40 -34
  7. data/lib/active_record/association_relation.rb +22 -0
  8. data/lib/active_record/associations/alias_tracker.rb +4 -2
  9. data/lib/active_record/associations/association.rb +60 -46
  10. data/lib/active_record/associations/association_scope.rb +46 -40
  11. data/lib/active_record/associations/belongs_to_association.rb +17 -4
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  13. data/lib/active_record/associations/builder/association.rb +81 -28
  14. data/lib/active_record/associations/builder/belongs_to.rb +73 -56
  15. data/lib/active_record/associations/builder/collection_association.rb +54 -40
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -64
  18. data/lib/active_record/associations/builder/has_one.rb +13 -50
  19. data/lib/active_record/associations/builder/singular_association.rb +13 -13
  20. data/lib/active_record/associations/collection_association.rb +130 -96
  21. data/lib/active_record/associations/collection_proxy.rb +916 -63
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +15 -13
  23. data/lib/active_record/associations/has_many_association.rb +35 -8
  24. data/lib/active_record/associations/has_many_through_association.rb +37 -17
  25. data/lib/active_record/associations/has_one_association.rb +42 -19
  26. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_association.rb +39 -22
  28. data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
  29. data/lib/active_record/associations/join_dependency/join_part.rb +21 -8
  30. data/lib/active_record/associations/join_dependency.rb +30 -9
  31. data/lib/active_record/associations/join_helper.rb +1 -11
  32. data/lib/active_record/associations/preloader/association.rb +29 -33
  33. data/lib/active_record/associations/preloader/collection_association.rb +1 -1
  34. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +2 -2
  35. data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
  36. data/lib/active_record/associations/preloader/has_one.rb +1 -1
  37. data/lib/active_record/associations/preloader/through_association.rb +13 -17
  38. data/lib/active_record/associations/preloader.rb +20 -43
  39. data/lib/active_record/associations/singular_association.rb +11 -11
  40. data/lib/active_record/associations/through_association.rb +3 -3
  41. data/lib/active_record/associations.rb +223 -282
  42. data/lib/active_record/attribute_assignment.rb +134 -154
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
  44. data/lib/active_record/attribute_methods/dirty.rb +36 -29
  45. data/lib/active_record/attribute_methods/primary_key.rb +45 -31
  46. data/lib/active_record/attribute_methods/query.rb +5 -4
  47. data/lib/active_record/attribute_methods/read.rb +67 -90
  48. data/lib/active_record/attribute_methods/serialization.rb +133 -70
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +51 -45
  50. data/lib/active_record/attribute_methods/write.rb +34 -39
  51. data/lib/active_record/attribute_methods.rb +268 -108
  52. data/lib/active_record/autosave_association.rb +80 -73
  53. data/lib/active_record/base.rb +54 -451
  54. data/lib/active_record/callbacks.rb +60 -22
  55. data/lib/active_record/coders/yaml_column.rb +18 -21
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +347 -197
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +146 -138
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -19
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +19 -3
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +151 -142
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +499 -217
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +208 -0
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +209 -44
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +169 -61
  67. data/lib/active_record/connection_adapters/column.rb +67 -36
  68. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +28 -29
  70. data/lib/active_record/connection_adapters/mysql_adapter.rb +200 -73
  71. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +98 -0
  72. data/lib/active_record/connection_adapters/postgresql/cast.rb +160 -0
  73. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +240 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid.rb +374 -0
  75. data/lib/active_record/connection_adapters/postgresql/quoting.rb +183 -0
  76. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  77. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +508 -0
  78. data/lib/active_record/connection_adapters/postgresql_adapter.rb +544 -899
  79. data/lib/active_record/connection_adapters/schema_cache.rb +76 -16
  80. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +595 -16
  81. data/lib/active_record/connection_handling.rb +98 -0
  82. data/lib/active_record/core.rb +472 -0
  83. data/lib/active_record/counter_cache.rb +107 -108
  84. data/lib/active_record/dynamic_matchers.rb +115 -63
  85. data/lib/active_record/errors.rb +36 -18
  86. data/lib/active_record/explain.rb +15 -63
  87. data/lib/active_record/explain_registry.rb +30 -0
  88. data/lib/active_record/explain_subscriber.rb +8 -4
  89. data/lib/active_record/fixture_set/file.rb +55 -0
  90. data/lib/active_record/fixtures.rb +159 -155
  91. data/lib/active_record/inheritance.rb +93 -59
  92. data/lib/active_record/integration.rb +8 -8
  93. data/lib/active_record/locale/en.yml +8 -1
  94. data/lib/active_record/locking/optimistic.rb +39 -43
  95. data/lib/active_record/locking/pessimistic.rb +4 -4
  96. data/lib/active_record/log_subscriber.rb +19 -9
  97. data/lib/active_record/migration/command_recorder.rb +102 -33
  98. data/lib/active_record/migration/join_table.rb +15 -0
  99. data/lib/active_record/migration.rb +411 -173
  100. data/lib/active_record/model_schema.rb +81 -94
  101. data/lib/active_record/nested_attributes.rb +173 -131
  102. data/lib/active_record/null_relation.rb +67 -0
  103. data/lib/active_record/persistence.rb +254 -106
  104. data/lib/active_record/query_cache.rb +18 -36
  105. data/lib/active_record/querying.rb +19 -15
  106. data/lib/active_record/railtie.rb +113 -38
  107. data/lib/active_record/railties/console_sandbox.rb +3 -4
  108. data/lib/active_record/railties/controller_runtime.rb +4 -3
  109. data/lib/active_record/railties/databases.rake +115 -368
  110. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  111. data/lib/active_record/readonly_attributes.rb +7 -3
  112. data/lib/active_record/reflection.rb +110 -61
  113. data/lib/active_record/relation/batches.rb +29 -29
  114. data/lib/active_record/relation/calculations.rb +155 -125
  115. data/lib/active_record/relation/delegation.rb +94 -18
  116. data/lib/active_record/relation/finder_methods.rb +151 -203
  117. data/lib/active_record/relation/merger.rb +188 -0
  118. data/lib/active_record/relation/predicate_builder.rb +85 -42
  119. data/lib/active_record/relation/query_methods.rb +793 -146
  120. data/lib/active_record/relation/spawn_methods.rb +43 -150
  121. data/lib/active_record/relation.rb +293 -173
  122. data/lib/active_record/result.rb +48 -7
  123. data/lib/active_record/runtime_registry.rb +17 -0
  124. data/lib/active_record/sanitization.rb +41 -54
  125. data/lib/active_record/schema.rb +19 -12
  126. data/lib/active_record/schema_dumper.rb +41 -41
  127. data/lib/active_record/schema_migration.rb +46 -0
  128. data/lib/active_record/scoping/default.rb +56 -52
  129. data/lib/active_record/scoping/named.rb +78 -103
  130. data/lib/active_record/scoping.rb +54 -124
  131. data/lib/active_record/serialization.rb +6 -2
  132. data/lib/active_record/serializers/xml_serializer.rb +9 -15
  133. data/lib/active_record/statement_cache.rb +26 -0
  134. data/lib/active_record/store.rb +131 -15
  135. data/lib/active_record/tasks/database_tasks.rb +204 -0
  136. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  137. data/lib/active_record/tasks/mysql_database_tasks.rb +144 -0
  138. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  139. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  140. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  141. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  142. data/lib/active_record/test_case.rb +67 -38
  143. data/lib/active_record/timestamp.rb +16 -11
  144. data/lib/active_record/transactions.rb +73 -51
  145. data/lib/active_record/validations/associated.rb +19 -13
  146. data/lib/active_record/validations/presence.rb +65 -0
  147. data/lib/active_record/validations/uniqueness.rb +110 -57
  148. data/lib/active_record/validations.rb +18 -17
  149. data/lib/active_record/version.rb +7 -6
  150. data/lib/active_record.rb +63 -45
  151. data/lib/rails/generators/active_record/migration/migration_generator.rb +45 -8
  152. data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
  153. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  154. data/lib/rails/generators/active_record/model/model_generator.rb +5 -4
  155. data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
  156. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  157. data/lib/rails/generators/active_record.rb +3 -5
  158. metadata +43 -29
  159. data/examples/associations.png +0 -0
  160. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  161. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  162. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  163. data/lib/active_record/dynamic_finder_match.rb +0 -68
  164. data/lib/active_record/dynamic_scope_match.rb +0 -23
  165. data/lib/active_record/fixtures/file.rb +0 -65
  166. data/lib/active_record/identity_map.rb +0 -162
  167. data/lib/active_record/observer.rb +0 -121
  168. data/lib/active_record/session_store.rb +0 -360
  169. data/lib/rails/generators/active_record/migration.rb +0 -15
  170. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  171. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  172. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  173. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -2,16 +2,16 @@ module ActiveRecord
2
2
  module Associations
3
3
  class Preloader
4
4
  class Association #:nodoc:
5
- attr_reader :owners, :reflection, :preload_options, :model, :klass
6
-
7
- def initialize(klass, owners, reflection, preload_options)
8
- @klass = klass
9
- @owners = owners
10
- @reflection = reflection
11
- @preload_options = preload_options || {}
12
- @model = owners.first && owners.first.class
13
- @scoped = nil
14
- @owners_by_key = nil
5
+ attr_reader :owners, :reflection, :preload_scope, :model, :klass
6
+
7
+ def initialize(klass, owners, reflection, preload_scope)
8
+ @klass = klass
9
+ @owners = owners
10
+ @reflection = reflection
11
+ @preload_scope = preload_scope
12
+ @model = owners.first && owners.first.class
13
+ @scope = nil
14
+ @owners_by_key = nil
15
15
  end
16
16
 
17
17
  def run
@@ -24,12 +24,12 @@ module ActiveRecord
24
24
  raise NotImplementedError
25
25
  end
26
26
 
27
- def scoped
28
- @scoped ||= build_scope
27
+ def scope
28
+ @scope ||= build_scope
29
29
  end
30
30
 
31
31
  def records_for(ids)
32
- scoped.where(association_key.in(ids))
32
+ scope.where(association_key.in(ids))
33
33
  end
34
34
 
35
35
  def table
@@ -76,8 +76,8 @@ module ActiveRecord
76
76
  else
77
77
  # Some databases impose a limit on the number of ids in a list (in Oracle it's 1000)
78
78
  # Make several smaller queries if necessary or make one query if the adapter supports it
79
- sliced = owner_keys.each_slice(model.connection.in_clause_length || owner_keys.size)
80
- records = sliced.map { |slice| records_for(slice) }.flatten
79
+ sliced = owner_keys.each_slice(klass.connection.in_clause_length || owner_keys.size)
80
+ records = sliced.map { |slice| records_for(slice).to_a }.flatten
81
81
  end
82
82
 
83
83
  # Each record may have multiple owners, and vice-versa
@@ -92,33 +92,29 @@ module ActiveRecord
92
92
  records_by_owner
93
93
  end
94
94
 
95
+ def reflection_scope
96
+ @reflection_scope ||= reflection.scope ? klass.unscoped.instance_exec(nil, &reflection.scope) : klass.unscoped
97
+ end
98
+
95
99
  def build_scope
96
- scope = klass.scoped
100
+ scope = klass.unscoped
101
+ scope.default_scoped = true
97
102
 
98
- scope = scope.where(process_conditions(options[:conditions]))
99
- scope = scope.where(process_conditions(preload_options[:conditions]))
103
+ values = reflection_scope.values
104
+ preload_values = preload_scope.values
100
105
 
101
- scope = scope.select(preload_options[:select] || options[:select] || table[Arel.star])
102
- scope = scope.includes(preload_options[:include] || options[:include])
106
+ scope.where_values = Array(values[:where]) + Array(preload_values[:where])
107
+ scope.references_values = Array(values[:references]) + Array(preload_values[:references])
108
+
109
+ scope._select! preload_values[:select] || values[:select] || table[Arel.star]
110
+ scope.includes! preload_values[:includes] || values[:includes]
103
111
 
104
112
  if options[:as]
105
- scope = scope.where(
106
- klass.table_name => {
107
- reflection.type => model.base_class.sti_name
108
- }
109
- )
113
+ scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
110
114
  end
111
115
 
112
116
  scope
113
117
  end
114
-
115
- def process_conditions(conditions)
116
- if conditions.respond_to?(:to_proc)
117
- conditions = klass.send(:instance_eval, &conditions)
118
- end
119
-
120
- conditions
121
- end
122
118
  end
123
119
  end
124
120
  end
@@ -6,7 +6,7 @@ module ActiveRecord
6
6
  private
7
7
 
8
8
  def build_scope
9
- super.order(preload_options[:order] || options[:order])
9
+ super.order(preload_scope.values[:order] || reflection_scope.values[:order])
10
10
  end
11
11
 
12
12
  def preload
@@ -6,7 +6,7 @@ module ActiveRecord
6
6
 
7
7
  def initialize(klass, records, reflection, preload_options)
8
8
  super
9
- @join_table = Arel::Table.new(options[:join_table]).alias('t0')
9
+ @join_table = Arel::Table.new(reflection.join_table).alias('t0')
10
10
  end
11
11
 
12
12
  # Unlike the other associations, we want to get a raw array of rows so that we can
@@ -35,7 +35,7 @@ module ActiveRecord
35
35
  # record
36
36
  def associated_records_by_owner
37
37
  records = {}
38
- super.each do |owner_key, rows|
38
+ super.each_value do |rows|
39
39
  rows.map! { |row| records[row[klass.primary_key]] ||= klass.instantiate(row) }
40
40
  end
41
41
  end
@@ -5,9 +5,13 @@ module ActiveRecord
5
5
  include ThroughAssociation
6
6
 
7
7
  def associated_records_by_owner
8
- super.each do |owner, records|
9
- records.uniq! if options[:uniq]
8
+ records_by_owner = super
9
+
10
+ if reflection_scope.distinct_value
11
+ records_by_owner.each_value { |records| records.uniq! }
10
12
  end
13
+
14
+ records_by_owner
11
15
  end
12
16
  end
13
17
  end
@@ -14,7 +14,7 @@ module ActiveRecord
14
14
  private
15
15
 
16
16
  def build_scope
17
- super.order(preload_options[:order] || options[:order])
17
+ super.order(preload_scope.values[:order] || reflection_scope.values[:order])
18
18
  end
19
19
 
20
20
  end
@@ -14,10 +14,7 @@ module ActiveRecord
14
14
  def associated_records_by_owner
15
15
  through_records = through_records_by_owner
16
16
 
17
- ActiveRecord::Associations::Preloader.new(
18
- through_records.values.flatten,
19
- source_reflection.name, options
20
- ).run
17
+ Preloader.new(through_records.values.flatten, source_reflection.name, reflection_scope).run
21
18
 
22
19
  through_records.each do |owner, records|
23
20
  records.map! { |r| r.send(source_reflection.name) }.flatten!
@@ -28,16 +25,13 @@ module ActiveRecord
28
25
  private
29
26
 
30
27
  def through_records_by_owner
31
- ActiveRecord::Associations::Preloader.new(
32
- owners, through_reflection.name,
33
- through_options
34
- ).run
28
+ Preloader.new(owners, through_reflection.name, through_scope).run
35
29
 
36
30
  Hash[owners.map do |owner|
37
31
  through_records = Array.wrap(owner.send(through_reflection.name))
38
32
 
39
33
  # Dont cache the association - we would only be caching a subset
40
- if (preload_options != through_options) ||
34
+ if (through_scope != through_reflection.klass.unscoped) ||
41
35
  (reflection.options[:source_type] && through_reflection.collection?)
42
36
  owner.association(through_reflection.name).reset
43
37
  end
@@ -46,20 +40,22 @@ module ActiveRecord
46
40
  end]
47
41
  end
48
42
 
49
- def through_options
50
- through_options = {}
43
+ def through_scope
44
+ through_scope = through_reflection.klass.unscoped
51
45
 
52
46
  if options[:source_type]
53
- through_options[:conditions] = { reflection.foreign_type => options[:source_type] }
47
+ through_scope.where! reflection.foreign_type => options[:source_type]
54
48
  else
55
- if options[:conditions]
56
- through_options[:include] = options[:include] || options[:source]
57
- through_options[:conditions] = options[:conditions]
49
+ unless reflection_scope.where_values.empty?
50
+ through_scope.includes_values = Array(reflection_scope.values[:includes] || options[:source])
51
+ through_scope.where_values = reflection_scope.values[:where]
58
52
  end
59
- through_options[:order] = options[:order] if options.has_key?(:order)
53
+
54
+ through_scope.references! reflection_scope.values[:references]
55
+ through_scope.order! reflection_scope.values[:order] if through_scope.eager_loading?
60
56
  end
61
57
 
62
- through_options
58
+ through_scope
63
59
  end
64
60
  end
65
61
  end
@@ -12,7 +12,7 @@ module ActiveRecord
12
12
  # and all of its books via a single query:
13
13
  #
14
14
  # SELECT * FROM authors
15
- # LEFT OUTER JOIN books ON authors.id = books.id
15
+ # LEFT OUTER JOIN books ON authors.id = books.author_id
16
16
  # WHERE authors.name = 'Ken Akamatsu'
17
17
  #
18
18
  # However, this could result in many rows that contain redundant data. After
@@ -46,7 +46,7 @@ module ActiveRecord
46
46
  autoload :BelongsTo, 'active_record/associations/preloader/belongs_to'
47
47
  end
48
48
 
49
- attr_reader :records, :associations, :options, :model
49
+ attr_reader :records, :associations, :preload_scope, :model
50
50
 
51
51
  # Eager loads the named associations for the given Active Record record(s).
52
52
  #
@@ -72,7 +72,7 @@ module ActiveRecord
72
72
  # books.
73
73
  # - a Hash which specifies multiple association names, as well as
74
74
  # association names for the to-be-preloaded association objects. For
75
- # example, specifying <tt>{ :author => :avatar }</tt> will preload a
75
+ # example, specifying <tt>{ author: :avatar }</tt> will preload a
76
76
  # book's author, as well as that author's avatar.
77
77
  #
78
78
  # +:associations+ has the same format as the +:include+ option for
@@ -80,17 +80,12 @@ module ActiveRecord
80
80
  #
81
81
  # :books
82
82
  # [ :books, :author ]
83
- # { :author => :avatar }
84
- # [ :books, { :author => :avatar } ]
85
- #
86
- # +options+ contains options that will be passed to ActiveRecord::Base#find
87
- # (which is called under the hood for preloading records). But it is passed
88
- # only one level deep in the +associations+ argument, i.e. it's not passed
89
- # to the child associations when +associations+ is a Hash.
90
- def initialize(records, associations, options = {})
91
- @records = Array.wrap(records).compact.uniq
92
- @associations = Array.wrap(associations)
93
- @options = options
83
+ # { author: :avatar }
84
+ # [ :books, { author: :avatar } ]
85
+ def initialize(records, associations, preload_scope = nil)
86
+ @records = Array.wrap(records).compact.uniq
87
+ @associations = Array.wrap(associations)
88
+ @preload_scope = preload_scope || Relation.new(nil, nil)
94
89
  end
95
90
 
96
91
  def run
@@ -105,7 +100,9 @@ module ActiveRecord
105
100
  case association
106
101
  when Hash
107
102
  preload_hash(association)
108
- when String, Symbol
103
+ when Symbol
104
+ preload_one(association)
105
+ when String
109
106
  preload_one(association.to_sym)
110
107
  else
111
108
  raise ArgumentError, "#{association.inspect} was not recognised for preload"
@@ -114,7 +111,7 @@ module ActiveRecord
114
111
 
115
112
  def preload_hash(association)
116
113
  association.each do |parent, child|
117
- Preloader.new(records, parent, options).run
114
+ Preloader.new(records, parent, preload_scope).run
118
115
  Preloader.new(records.map { |record| record.send(parent) }.flatten, child).run
119
116
  end
120
117
  end
@@ -129,39 +126,19 @@ module ActiveRecord
129
126
  def preload_one(association)
130
127
  grouped_records(association).each do |reflection, klasses|
131
128
  klasses.each do |klass, records|
132
- preloader_for(reflection).new(klass, records, reflection, options).run
129
+ preloader_for(reflection).new(klass, records, reflection, preload_scope).run
133
130
  end
134
131
  end
135
132
  end
136
133
 
137
134
  def grouped_records(association)
138
- Hash[
139
- records_by_reflection(association).map do |reflection, records|
140
- [reflection, records.group_by { |record| association_klass(reflection, record) }]
141
- end
142
- ]
143
- end
144
-
145
- def records_by_reflection(association)
146
- records.group_by do |record|
147
- reflection = record.class.reflections[association]
148
-
149
- unless reflection
150
- raise ActiveRecord::ConfigurationError, "Association named '#{association}' was not found; " \
151
- "perhaps you misspelled it?"
152
- end
153
-
154
- reflection
155
- end
156
- end
157
-
158
- def association_klass(reflection, record)
159
- if reflection.macro == :belongs_to && reflection.options[:polymorphic]
160
- klass = record.send(reflection.foreign_type)
161
- klass && klass.constantize
162
- else
163
- reflection.klass
135
+ h = {}
136
+ records.each do |record|
137
+ assoc = record.association(association)
138
+ klasses = h[assoc.reflection] ||= {}
139
+ (klasses[assoc.klass] ||= []) << record
164
140
  end
141
+ h
165
142
  end
166
143
 
167
144
  def preloader_for(reflection)
@@ -12,21 +12,21 @@ module ActiveRecord
12
12
  target
13
13
  end
14
14
 
15
- # Implements the writer method, e.g. foo.items= for Foo.has_many :items
15
+ # Implements the writer method, e.g. foo.bar= for Foo.belongs_to :bar
16
16
  def writer(record)
17
17
  replace(record)
18
18
  end
19
19
 
20
- def create(attributes = {}, options = {}, &block)
21
- create_record(attributes, options, &block)
20
+ def create(attributes = {}, &block)
21
+ _create_record(attributes, &block)
22
22
  end
23
23
 
24
- def create!(attributes = {}, options = {}, &block)
25
- create_record(attributes, options, true, &block)
24
+ def create!(attributes = {}, &block)
25
+ _create_record(attributes, true, &block)
26
26
  end
27
27
 
28
- def build(attributes = {}, options = {})
29
- record = build_record(attributes, options)
28
+ def build(attributes = {})
29
+ record = build_record(attributes)
30
30
  yield(record) if block_given?
31
31
  set_new_record(record)
32
32
  record
@@ -35,11 +35,11 @@ module ActiveRecord
35
35
  private
36
36
 
37
37
  def create_scope
38
- scoped.scope_for_create.stringify_keys.except(klass.primary_key)
38
+ scope.scope_for_create.stringify_keys.except(klass.primary_key)
39
39
  end
40
40
 
41
41
  def find_target
42
- scoped.first.tap { |record| set_inverse_instance(record) }
42
+ scope.take.tap { |record| set_inverse_instance(record) }
43
43
  end
44
44
 
45
45
  # Implemented by subclasses
@@ -51,8 +51,8 @@ module ActiveRecord
51
51
  replace(record)
52
52
  end
53
53
 
54
- def create_record(attributes, options, raise_error = false)
55
- record = build_record(attributes, options)
54
+ def _create_record(attributes, raise_error = false)
55
+ record = build_record(attributes)
56
56
  yield(record) if block_given?
57
57
  saved = record.save
58
58
  set_new_record(record)
@@ -14,8 +14,8 @@ module ActiveRecord
14
14
  def target_scope
15
15
  scope = super
16
16
  chain[1..-1].each do |reflection|
17
- scope = scope.merge(
18
- reflection.klass.scoped.with_default_scope.
17
+ scope.merge!(
18
+ reflection.klass.all.with_default_scope.
19
19
  except(:select, :create_with, :includes, :preload, :joins, :eager_load)
20
20
  )
21
21
  end
@@ -28,7 +28,7 @@ module ActiveRecord
28
28
  # methods which create and delete records on the association.
29
29
  #
30
30
  # We only support indirectly modifying through associations which has a belongs_to source.
31
- # This is the "has_many :tags, :through => :taggings" situation, where the join model
31
+ # This is the "has_many :tags, through: :taggings" situation, where the join model
32
32
  # typically has a belongs_to on both side. In other words, associations which could also
33
33
  # be represented as has_and_belongs_to_many associations.
34
34
  #