activerecord 3.0.0 → 4.0.0

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 (181) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2102 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +35 -44
  5. data/examples/performance.rb +110 -100
  6. data/lib/active_record/aggregations.rb +59 -75
  7. data/lib/active_record/associations/alias_tracker.rb +76 -0
  8. data/lib/active_record/associations/association.rb +248 -0
  9. data/lib/active_record/associations/association_scope.rb +135 -0
  10. data/lib/active_record/associations/belongs_to_association.rb +60 -59
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -59
  12. data/lib/active_record/associations/builder/association.rb +108 -0
  13. data/lib/active_record/associations/builder/belongs_to.rb +98 -0
  14. data/lib/active_record/associations/builder/collection_association.rb +89 -0
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +39 -0
  16. data/lib/active_record/associations/builder/has_many.rb +15 -0
  17. data/lib/active_record/associations/builder/has_one.rb +25 -0
  18. data/lib/active_record/associations/builder/singular_association.rb +32 -0
  19. data/lib/active_record/associations/collection_association.rb +608 -0
  20. data/lib/active_record/associations/collection_proxy.rb +986 -0
  21. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +40 -112
  22. data/lib/active_record/associations/has_many_association.rb +83 -76
  23. data/lib/active_record/associations/has_many_through_association.rb +147 -66
  24. data/lib/active_record/associations/has_one_association.rb +67 -108
  25. data/lib/active_record/associations/has_one_through_association.rb +21 -25
  26. data/lib/active_record/associations/join_dependency/join_association.rb +174 -0
  27. data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
  28. data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
  29. data/lib/active_record/associations/join_dependency.rb +235 -0
  30. data/lib/active_record/associations/join_helper.rb +45 -0
  31. data/lib/active_record/associations/preloader/association.rb +121 -0
  32. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  33. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  34. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
  35. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  36. data/lib/active_record/associations/preloader/has_many_through.rb +19 -0
  37. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  38. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  39. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  40. data/lib/active_record/associations/preloader/through_association.rb +63 -0
  41. data/lib/active_record/associations/preloader.rb +178 -0
  42. data/lib/active_record/associations/singular_association.rb +64 -0
  43. data/lib/active_record/associations/through_association.rb +87 -0
  44. data/lib/active_record/associations.rb +512 -1224
  45. data/lib/active_record/attribute_assignment.rb +201 -0
  46. data/lib/active_record/attribute_methods/before_type_cast.rb +49 -12
  47. data/lib/active_record/attribute_methods/dirty.rb +51 -28
  48. data/lib/active_record/attribute_methods/primary_key.rb +94 -22
  49. data/lib/active_record/attribute_methods/query.rb +5 -4
  50. data/lib/active_record/attribute_methods/read.rb +63 -72
  51. data/lib/active_record/attribute_methods/serialization.rb +162 -0
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -41
  53. data/lib/active_record/attribute_methods/write.rb +39 -13
  54. data/lib/active_record/attribute_methods.rb +362 -29
  55. data/lib/active_record/autosave_association.rb +132 -75
  56. data/lib/active_record/base.rb +83 -1627
  57. data/lib/active_record/callbacks.rb +69 -47
  58. data/lib/active_record/coders/yaml_column.rb +38 -0
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +411 -138
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +21 -11
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -173
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +36 -22
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +82 -25
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +176 -414
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +562 -232
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +281 -53
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +782 -0
  70. data/lib/active_record/connection_adapters/column.rb +318 -0
  71. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +273 -0
  73. data/lib/active_record/connection_adapters/mysql_adapter.rb +365 -450
  74. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
  75. data/lib/active_record/connection_adapters/postgresql/cast.rb +152 -0
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
  77. data/lib/active_record/connection_adapters/postgresql/oid.rb +366 -0
  78. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -0
  79. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  80. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +489 -0
  81. data/lib/active_record/connection_adapters/postgresql_adapter.rb +672 -752
  82. data/lib/active_record/connection_adapters/schema_cache.rb +129 -0
  83. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +588 -17
  84. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  85. data/lib/active_record/connection_handling.rb +98 -0
  86. data/lib/active_record/core.rb +463 -0
  87. data/lib/active_record/counter_cache.rb +108 -101
  88. data/lib/active_record/dynamic_matchers.rb +131 -0
  89. data/lib/active_record/errors.rb +54 -13
  90. data/lib/active_record/explain.rb +38 -0
  91. data/lib/active_record/explain_registry.rb +30 -0
  92. data/lib/active_record/explain_subscriber.rb +29 -0
  93. data/lib/active_record/fixture_set/file.rb +55 -0
  94. data/lib/active_record/fixtures.rb +703 -785
  95. data/lib/active_record/inheritance.rb +200 -0
  96. data/lib/active_record/integration.rb +60 -0
  97. data/lib/active_record/locale/en.yml +8 -1
  98. data/lib/active_record/locking/optimistic.rb +69 -60
  99. data/lib/active_record/locking/pessimistic.rb +34 -12
  100. data/lib/active_record/log_subscriber.rb +40 -6
  101. data/lib/active_record/migration/command_recorder.rb +164 -0
  102. data/lib/active_record/migration/join_table.rb +15 -0
  103. data/lib/active_record/migration.rb +614 -216
  104. data/lib/active_record/model_schema.rb +345 -0
  105. data/lib/active_record/nested_attributes.rb +248 -119
  106. data/lib/active_record/null_relation.rb +65 -0
  107. data/lib/active_record/persistence.rb +275 -57
  108. data/lib/active_record/query_cache.rb +29 -9
  109. data/lib/active_record/querying.rb +62 -0
  110. data/lib/active_record/railtie.rb +135 -21
  111. data/lib/active_record/railties/console_sandbox.rb +5 -0
  112. data/lib/active_record/railties/controller_runtime.rb +17 -5
  113. data/lib/active_record/railties/databases.rake +249 -359
  114. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  115. data/lib/active_record/readonly_attributes.rb +30 -0
  116. data/lib/active_record/reflection.rb +283 -103
  117. data/lib/active_record/relation/batches.rb +38 -34
  118. data/lib/active_record/relation/calculations.rb +252 -139
  119. data/lib/active_record/relation/delegation.rb +125 -0
  120. data/lib/active_record/relation/finder_methods.rb +182 -188
  121. data/lib/active_record/relation/merger.rb +161 -0
  122. data/lib/active_record/relation/predicate_builder.rb +86 -21
  123. data/lib/active_record/relation/query_methods.rb +917 -134
  124. data/lib/active_record/relation/spawn_methods.rb +53 -92
  125. data/lib/active_record/relation.rb +405 -143
  126. data/lib/active_record/result.rb +67 -0
  127. data/lib/active_record/runtime_registry.rb +17 -0
  128. data/lib/active_record/sanitization.rb +168 -0
  129. data/lib/active_record/schema.rb +20 -14
  130. data/lib/active_record/schema_dumper.rb +55 -46
  131. data/lib/active_record/schema_migration.rb +39 -0
  132. data/lib/active_record/scoping/default.rb +146 -0
  133. data/lib/active_record/scoping/named.rb +175 -0
  134. data/lib/active_record/scoping.rb +82 -0
  135. data/lib/active_record/serialization.rb +8 -46
  136. data/lib/active_record/serializers/xml_serializer.rb +21 -68
  137. data/lib/active_record/statement_cache.rb +26 -0
  138. data/lib/active_record/store.rb +156 -0
  139. data/lib/active_record/tasks/database_tasks.rb +203 -0
  140. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  141. data/lib/active_record/tasks/mysql_database_tasks.rb +143 -0
  142. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  143. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  144. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  145. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  146. data/lib/active_record/test_case.rb +57 -28
  147. data/lib/active_record/timestamp.rb +49 -18
  148. data/lib/active_record/transactions.rb +106 -63
  149. data/lib/active_record/translation.rb +22 -0
  150. data/lib/active_record/validations/associated.rb +25 -24
  151. data/lib/active_record/validations/presence.rb +65 -0
  152. data/lib/active_record/validations/uniqueness.rb +123 -83
  153. data/lib/active_record/validations.rb +29 -29
  154. data/lib/active_record/version.rb +7 -5
  155. data/lib/active_record.rb +83 -34
  156. data/lib/rails/generators/active_record/migration/migration_generator.rb +46 -9
  157. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +19 -0
  158. data/lib/rails/generators/active_record/migration/templates/migration.rb +30 -8
  159. data/lib/rails/generators/active_record/model/model_generator.rb +15 -5
  160. data/lib/rails/generators/active_record/model/templates/model.rb +7 -2
  161. data/lib/rails/generators/active_record/model/templates/module.rb +3 -1
  162. data/lib/rails/generators/active_record.rb +4 -8
  163. metadata +163 -121
  164. data/CHANGELOG +0 -6023
  165. data/examples/associations.png +0 -0
  166. data/lib/active_record/association_preload.rb +0 -403
  167. data/lib/active_record/associations/association_collection.rb +0 -562
  168. data/lib/active_record/associations/association_proxy.rb +0 -295
  169. data/lib/active_record/associations/through_association_scope.rb +0 -154
  170. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -113
  171. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -401
  172. data/lib/active_record/dynamic_finder_match.rb +0 -53
  173. data/lib/active_record/dynamic_scope_match.rb +0 -32
  174. data/lib/active_record/named_scope.rb +0 -138
  175. data/lib/active_record/observer.rb +0 -140
  176. data/lib/active_record/session_store.rb +0 -340
  177. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -16
  178. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  179. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -2
  180. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -24
  181. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -16
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/array/wrap'
2
-
3
1
  module ActiveRecord
4
2
  # = Active Record Callbacks
5
3
  #
@@ -25,15 +23,19 @@ module ActiveRecord
25
23
  # Check out <tt>ActiveRecord::Transactions</tt> for more details about <tt>after_commit</tt> and
26
24
  # <tt>after_rollback</tt>.
27
25
  #
28
- # That's a total of ten callbacks, which gives you immense power to react and prepare for each state in the
26
+ # Lastly an <tt>after_find</tt> and <tt>after_initialize</tt> callback is triggered for each object that
27
+ # is found and instantiated by a finder, with <tt>after_initialize</tt> being triggered after new objects
28
+ # are instantiated as well.
29
+ #
30
+ # That's a total of twelve callbacks, which gives you immense power to react and prepare for each state in the
29
31
  # Active Record life cycle. The sequence for calling <tt>Base#save</tt> for an existing record is similar,
30
- # except that each <tt>_on_create</tt> callback is replaced by the corresponding <tt>_on_update</tt> callback.
32
+ # except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback.
31
33
  #
32
34
  # Examples:
33
35
  # class CreditCard < ActiveRecord::Base
34
36
  # # Strip everything but digits, so the user can specify "555 234 34" or
35
- # # "5552-3434" or both will mean "55523434"
36
- # before_validation(:on => :create) do
37
+ # # "5552-3434" and both will mean "55523434"
38
+ # before_validation(on: :create) do
37
39
  # self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
38
40
  # end
39
41
  # end
@@ -69,7 +71,7 @@ module ActiveRecord
69
71
  #
70
72
  # Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
71
73
  # run, both +destroy_author+ and +destroy_readers+ are called. Contrast this to the following situation
72
- # where the +before_destroy+ methis is overriden:
74
+ # where the +before_destroy+ method is overridden:
73
75
  #
74
76
  # class Topic < ActiveRecord::Base
75
77
  # def before_destroy() destroy_author end
@@ -81,7 +83,7 @@ module ActiveRecord
81
83
  #
82
84
  # In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
83
85
  # So, use the callback macros when you want to ensure that a certain callback is called for the entire
84
- # hierarchy, and use the regular overwriteable methods when you want to leave it up to each descendant
86
+ # hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant
85
87
  # to decide whether they want to call +super+ and trigger the inherited callbacks.
86
88
  #
87
89
  # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
@@ -185,14 +187,6 @@ module ActiveRecord
185
187
  # 'puts "Evaluated after parents are destroyed"'
186
188
  # end
187
189
  #
188
- # == The +after_find+ and +after_initialize+ exceptions
189
- #
190
- # Because +after_find+ and +after_initialize+ are called for each object found and instantiated by a finder,
191
- # such as <tt>Base.find(:all)</tt>, we've had to implement a simple performance constraint (50% more speed
192
- # on a simple test case). Unlike all the other callbacks, +after_find+ and +after_initialize+ will only be
193
- # run if an explicit implementation is defined (<tt>def after_find</tt>). In that case, all of the
194
- # callback types will be called.
195
- #
196
190
  # == <tt>before_validation*</tt> returning statements
197
191
  #
198
192
  # If the returning value of a +before_validation+ callback can be evaluated to +false+, the process will be
@@ -206,6 +200,40 @@ module ActiveRecord
206
200
  # Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
207
201
  # methods on the model, which are called last.
208
202
  #
203
+ # == Ordering callbacks
204
+ #
205
+ # Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+
206
+ # callback (+log_children+ in this case) should be executed before the children get destroyed by the +dependent: destroy+ option.
207
+ #
208
+ # Let's look at the code below:
209
+ #
210
+ # class Topic < ActiveRecord::Base
211
+ # has_many :children, dependent: destroy
212
+ #
213
+ # before_destroy :log_children
214
+ #
215
+ # private
216
+ # def log_children
217
+ # # Child processing
218
+ # end
219
+ # end
220
+ #
221
+ # In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available
222
+ # because the +destroy+ callback gets executed first. You can use the +prepend+ option on the +before_destroy+ callback to avoid this.
223
+ #
224
+ # class Topic < ActiveRecord::Base
225
+ # has_many :children, dependent: destroy
226
+ #
227
+ # before_destroy :log_children, prepend: true
228
+ #
229
+ # private
230
+ # def log_children
231
+ # # Child processing
232
+ # end
233
+ # end
234
+ #
235
+ # This way, the +before_destroy+ gets executed before the <tt>dependent: destroy</tt> is called, and the data is still available.
236
+ #
209
237
  # == Transactions
210
238
  #
211
239
  # The entire callback chain of a +save+, <tt>save!</tt>, or +destroy+ call runs
@@ -220,13 +248,21 @@ module ActiveRecord
220
248
  #
221
249
  # == Debugging callbacks
222
250
  #
223
- # To list the methods and procs registered with a particular callback, append <tt>_callback_chain</tt> to
224
- # the callback name that you wish to list and send that to your class from the Rails console:
251
+ # The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. ActiveModel Callbacks support
252
+ # <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
253
+ # defines what part of the chain the callback runs in.
254
+ #
255
+ # To find all callbacks in the before_save callback chain:
256
+ #
257
+ # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
258
+ #
259
+ # Returns an array of callback objects that form the before_save chain.
260
+ #
261
+ # To further check if the before_save chain contains a proc defined as <tt>rest_when_dead</tt> use the <tt>filter</tt> property of the callback object:
225
262
  #
226
- # >> Topic.after_save_callback_chain
227
- # => [#<ActiveSupport::Callbacks::Callback:0x3f6a448
228
- # @method=#<Proc:0x03f9a42c@/Users/foo/bar/app/models/topic.rb:43>, kind:after_save, identifiernil,
229
- # options{}]
263
+ # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
264
+ #
265
+ # Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.
230
266
  #
231
267
  module Callbacks
232
268
  extend ActiveSupport::Concern
@@ -238,51 +274,37 @@ module ActiveRecord
238
274
  :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
239
275
  ]
240
276
 
277
+ module ClassMethods
278
+ include ActiveModel::Callbacks
279
+ end
280
+
241
281
  included do
242
- extend ActiveModel::Callbacks
243
282
  include ActiveModel::Validations::Callbacks
244
283
 
245
284
  define_model_callbacks :initialize, :find, :touch, :only => :after
246
285
  define_model_callbacks :save, :create, :update, :destroy
247
286
  end
248
287
 
249
- module ClassMethods
250
- def method_added(meth)
251
- super
252
- if CALLBACKS.include?(meth.to_sym)
253
- ActiveSupport::Deprecation.warn("Base##{meth} has been deprecated, please use Base.#{meth} :method instead", caller[0,1])
254
- send(meth.to_sym, meth.to_sym)
255
- end
256
- end
257
- end
258
-
259
288
  def destroy #:nodoc:
260
- _run_destroy_callbacks { super }
289
+ run_callbacks(:destroy) { super }
261
290
  end
262
291
 
263
292
  def touch(*) #:nodoc:
264
- _run_touch_callbacks { super }
265
- end
266
-
267
- def deprecated_callback_method(symbol) #:nodoc:
268
- if respond_to?(symbol, true)
269
- ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base##{symbol} :method_name instead")
270
- send(symbol)
271
- end
293
+ run_callbacks(:touch) { super }
272
294
  end
273
295
 
274
296
  private
275
297
 
276
298
  def create_or_update #:nodoc:
277
- _run_save_callbacks { super }
299
+ run_callbacks(:save) { super }
278
300
  end
279
301
 
280
- def create #:nodoc:
281
- _run_create_callbacks { super }
302
+ def create_record #:nodoc:
303
+ run_callbacks(:create) { super }
282
304
  end
283
305
 
284
- def update(*) #:nodoc:
285
- _run_update_callbacks { super }
306
+ def update_record(*) #:nodoc:
307
+ run_callbacks(:update) { super }
286
308
  end
287
309
  end
288
310
  end
@@ -0,0 +1,38 @@
1
+ require 'yaml'
2
+
3
+ module ActiveRecord
4
+ module Coders # :nodoc:
5
+ class YAMLColumn # :nodoc:
6
+
7
+ attr_accessor :object_class
8
+
9
+ def initialize(object_class = Object)
10
+ @object_class = object_class
11
+ end
12
+
13
+ def dump(obj)
14
+ return if obj.nil?
15
+
16
+ unless obj.is_a?(object_class)
17
+ raise SerializationTypeMismatch,
18
+ "Attribute was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}"
19
+ end
20
+ YAML.dump obj
21
+ end
22
+
23
+ def load(yaml)
24
+ return object_class.new if object_class != Object && yaml.nil?
25
+ return yaml unless yaml.is_a?(String) && yaml =~ /^---/
26
+ obj = YAML.load(yaml)
27
+
28
+ unless obj.is_a?(object_class) || obj.nil?
29
+ raise SerializationTypeMismatch,
30
+ "Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
31
+ end
32
+ obj ||= object_class.new if object_class != Object
33
+
34
+ obj
35
+ end
36
+ end
37
+ end
38
+ end