activerecord 4.1.16 → 4.2.0.beta1

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +634 -2185
  3. data/README.rdoc +15 -10
  4. data/lib/active_record.rb +2 -1
  5. data/lib/active_record/aggregations.rb +12 -8
  6. data/lib/active_record/associations.rb +58 -33
  7. data/lib/active_record/associations/association.rb +1 -1
  8. data/lib/active_record/associations/association_scope.rb +53 -21
  9. data/lib/active_record/associations/belongs_to_association.rb +15 -5
  10. data/lib/active_record/associations/builder/association.rb +16 -5
  11. data/lib/active_record/associations/builder/belongs_to.rb +7 -29
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -11
  13. data/lib/active_record/associations/builder/has_one.rb +2 -2
  14. data/lib/active_record/associations/builder/singular_association.rb +8 -1
  15. data/lib/active_record/associations/collection_association.rb +32 -44
  16. data/lib/active_record/associations/collection_proxy.rb +1 -10
  17. data/lib/active_record/associations/has_many_association.rb +60 -14
  18. data/lib/active_record/associations/has_many_through_association.rb +34 -23
  19. data/lib/active_record/associations/has_one_association.rb +0 -1
  20. data/lib/active_record/associations/join_dependency.rb +7 -9
  21. data/lib/active_record/associations/join_dependency/join_association.rb +18 -14
  22. data/lib/active_record/associations/preloader.rb +2 -2
  23. data/lib/active_record/associations/preloader/association.rb +9 -5
  24. data/lib/active_record/associations/preloader/through_association.rb +3 -3
  25. data/lib/active_record/associations/singular_association.rb +16 -1
  26. data/lib/active_record/associations/through_association.rb +6 -22
  27. data/lib/active_record/attribute.rb +131 -0
  28. data/lib/active_record/attribute_assignment.rb +19 -11
  29. data/lib/active_record/attribute_decorators.rb +66 -0
  30. data/lib/active_record/attribute_methods.rb +53 -90
  31. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -2
  32. data/lib/active_record/attribute_methods/dirty.rb +85 -42
  33. data/lib/active_record/attribute_methods/primary_key.rb +6 -8
  34. data/lib/active_record/attribute_methods/read.rb +14 -57
  35. data/lib/active_record/attribute_methods/serialization.rb +12 -146
  36. data/lib/active_record/attribute_methods/time_zone_conversion.rb +32 -40
  37. data/lib/active_record/attribute_methods/write.rb +8 -23
  38. data/lib/active_record/attribute_set.rb +77 -0
  39. data/lib/active_record/attribute_set/builder.rb +32 -0
  40. data/lib/active_record/attributes.rb +122 -0
  41. data/lib/active_record/autosave_association.rb +11 -21
  42. data/lib/active_record/base.rb +9 -19
  43. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +69 -45
  44. data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -42
  45. data/lib/active_record/connection_adapters/abstract/quoting.rb +59 -60
  46. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +37 -2
  47. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +102 -21
  48. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +9 -33
  49. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +178 -55
  50. data/lib/active_record/connection_adapters/abstract/transaction.rb +120 -115
  51. data/lib/active_record/connection_adapters/abstract_adapter.rb +143 -57
  52. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +156 -107
  53. data/lib/active_record/connection_adapters/column.rb +13 -244
  54. data/lib/active_record/connection_adapters/connection_specification.rb +6 -20
  55. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -15
  56. data/lib/active_record/connection_adapters/mysql_adapter.rb +55 -143
  57. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +15 -27
  58. data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
  59. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +39 -20
  60. data/lib/active_record/connection_adapters/postgresql/oid.rb +29 -388
  61. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +96 -0
  62. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  63. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  64. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +14 -0
  65. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
  66. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
  67. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +27 -0
  68. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  69. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +17 -0
  70. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
  71. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  72. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  73. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
  75. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  77. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
  78. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  79. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +76 -0
  80. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -0
  81. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
  82. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +85 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +26 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  86. data/lib/active_record/connection_adapters/postgresql/quoting.rb +42 -122
  87. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +4 -4
  88. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +154 -0
  89. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +86 -34
  90. data/lib/active_record/connection_adapters/postgresql/utils.rb +66 -0
  91. data/lib/active_record/connection_adapters/postgresql_adapter.rb +188 -452
  92. data/lib/active_record/connection_adapters/schema_cache.rb +14 -28
  93. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +54 -47
  94. data/lib/active_record/connection_handling.rb +1 -1
  95. data/lib/active_record/core.rb +119 -22
  96. data/lib/active_record/counter_cache.rb +60 -6
  97. data/lib/active_record/enum.rb +9 -10
  98. data/lib/active_record/errors.rb +27 -26
  99. data/lib/active_record/explain.rb +1 -1
  100. data/lib/active_record/fixtures.rb +52 -45
  101. data/lib/active_record/gem_version.rb +3 -3
  102. data/lib/active_record/inheritance.rb +33 -8
  103. data/lib/active_record/integration.rb +4 -4
  104. data/lib/active_record/locking/optimistic.rb +34 -16
  105. data/lib/active_record/migration.rb +22 -32
  106. data/lib/active_record/migration/command_recorder.rb +19 -2
  107. data/lib/active_record/migration/join_table.rb +1 -1
  108. data/lib/active_record/model_schema.rb +39 -48
  109. data/lib/active_record/nested_attributes.rb +8 -18
  110. data/lib/active_record/persistence.rb +39 -22
  111. data/lib/active_record/query_cache.rb +3 -3
  112. data/lib/active_record/querying.rb +1 -8
  113. data/lib/active_record/railtie.rb +17 -10
  114. data/lib/active_record/railties/databases.rake +47 -42
  115. data/lib/active_record/readonly_attributes.rb +0 -1
  116. data/lib/active_record/reflection.rb +225 -92
  117. data/lib/active_record/relation.rb +35 -11
  118. data/lib/active_record/relation/batches.rb +0 -2
  119. data/lib/active_record/relation/calculations.rb +28 -32
  120. data/lib/active_record/relation/delegation.rb +1 -1
  121. data/lib/active_record/relation/finder_methods.rb +42 -20
  122. data/lib/active_record/relation/merger.rb +0 -1
  123. data/lib/active_record/relation/predicate_builder.rb +1 -22
  124. data/lib/active_record/relation/predicate_builder/array_handler.rb +16 -11
  125. data/lib/active_record/relation/predicate_builder/relation_handler.rb +0 -4
  126. data/lib/active_record/relation/query_methods.rb +98 -62
  127. data/lib/active_record/relation/spawn_methods.rb +6 -7
  128. data/lib/active_record/result.rb +16 -9
  129. data/lib/active_record/sanitization.rb +8 -1
  130. data/lib/active_record/schema.rb +0 -1
  131. data/lib/active_record/schema_dumper.rb +51 -9
  132. data/lib/active_record/schema_migration.rb +4 -0
  133. data/lib/active_record/scoping/default.rb +5 -4
  134. data/lib/active_record/serializers/xml_serializer.rb +3 -7
  135. data/lib/active_record/statement_cache.rb +79 -5
  136. data/lib/active_record/store.rb +5 -5
  137. data/lib/active_record/tasks/database_tasks.rb +37 -5
  138. data/lib/active_record/tasks/mysql_database_tasks.rb +10 -16
  139. data/lib/active_record/tasks/postgresql_database_tasks.rb +2 -2
  140. data/lib/active_record/timestamp.rb +9 -7
  141. data/lib/active_record/transactions.rb +35 -21
  142. data/lib/active_record/type.rb +20 -0
  143. data/lib/active_record/type/binary.rb +40 -0
  144. data/lib/active_record/type/boolean.rb +19 -0
  145. data/lib/active_record/type/date.rb +46 -0
  146. data/lib/active_record/type/date_time.rb +43 -0
  147. data/lib/active_record/type/decimal.rb +40 -0
  148. data/lib/active_record/type/decimal_without_scale.rb +11 -0
  149. data/lib/active_record/type/float.rb +19 -0
  150. data/lib/active_record/type/hash_lookup_type_map.rb +19 -0
  151. data/lib/active_record/type/integer.rb +23 -0
  152. data/lib/active_record/type/mutable.rb +16 -0
  153. data/lib/active_record/type/numeric.rb +36 -0
  154. data/lib/active_record/type/serialized.rb +51 -0
  155. data/lib/active_record/type/string.rb +36 -0
  156. data/lib/active_record/type/text.rb +11 -0
  157. data/lib/active_record/type/time.rb +26 -0
  158. data/lib/active_record/type/time_value.rb +38 -0
  159. data/lib/active_record/type/type_map.rb +48 -0
  160. data/lib/active_record/type/value.rb +101 -0
  161. data/lib/active_record/validations.rb +21 -16
  162. data/lib/active_record/validations/uniqueness.rb +9 -23
  163. data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -4
  164. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +1 -1
  165. data/lib/rails/generators/active_record/model/templates/model.rb +1 -1
  166. metadata +71 -14
  167. data/lib/active_record/connection_adapters/postgresql/cast.rb +0 -168
@@ -307,7 +307,7 @@ module ActiveRecord
307
307
  attr_names.each do |association_name|
308
308
  if reflection = _reflect_on_association(association_name)
309
309
  reflection.autosave = true
310
- define_autosave_validation_callbacks(reflection)
310
+ add_autosave_association_callbacks(reflection)
311
311
 
312
312
  nested_attributes_options = self.nested_attributes_options.dup
313
313
  nested_attributes_options[association_name.to_sym] = options
@@ -485,10 +485,10 @@ module ActiveRecord
485
485
  end
486
486
 
487
487
  # Takes in a limit and checks if the attributes_collection has too many
488
- # records. The method will take limits in the form of symbols, procs, and
489
- # number-like objects (anything that can be compared with an integer).
488
+ # records. It accepts limit in the form of symbol, proc, or
489
+ # number-like object (anything that can be compared with an integer).
490
490
  #
491
- # Will raise an TooManyRecords error if the attributes_collection is
491
+ # Raises TooManyRecords error if the attributes_collection is
492
492
  # larger than the limit.
493
493
  def check_record_limit!(limit, attributes_collection)
494
494
  if limit
@@ -516,14 +516,14 @@ module ActiveRecord
516
516
 
517
517
  # Determines if a hash contains a truthy _destroy key.
518
518
  def has_destroy_flag?(hash)
519
- ConnectionAdapters::Column.value_to_boolean(hash['_destroy'])
519
+ Type::Boolean.new.type_cast_from_user(hash['_destroy'])
520
520
  end
521
521
 
522
- # Determines if a new record should be build by checking for
522
+ # Determines if a new record should be rejected by checking
523
523
  # has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
524
524
  # association and evaluates to +true+.
525
525
  def reject_new_record?(association_name, attributes)
526
- will_be_destroyed?(association_name, attributes) || call_reject_if(association_name, attributes)
526
+ has_destroy_flag?(attributes) || call_reject_if(association_name, attributes)
527
527
  end
528
528
 
529
529
  # Determines if a record with the particular +attributes+ should be
@@ -532,8 +532,7 @@ module ActiveRecord
532
532
  #
533
533
  # Returns false if there is a +destroy_flag+ on the attributes.
534
534
  def call_reject_if(association_name, attributes)
535
- return false if will_be_destroyed?(association_name, attributes)
536
-
535
+ return false if has_destroy_flag?(attributes)
537
536
  case callback = self.nested_attributes_options[association_name][:reject_if]
538
537
  when Symbol
539
538
  method(callback).arity == 0 ? send(callback) : send(callback, attributes)
@@ -542,15 +541,6 @@ module ActiveRecord
542
541
  end
543
542
  end
544
543
 
545
- # Only take into account the destroy flag if <tt>:allow_destroy</tt> is true
546
- def will_be_destroyed?(association_name, attributes)
547
- allow_destroy?(association_name) && has_destroy_flag?(attributes)
548
- end
549
-
550
- def allow_destroy?(association_name)
551
- self.nested_attributes_options[association_name][:allow_destroy]
552
- end
553
-
554
544
  def raise_nested_attributes_record_not_found!(association_name, record_id)
555
545
  raise RecordNotFound, "Couldn't find #{self.class._reflect_on_association(association_name).klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
556
546
  end
@@ -36,6 +36,23 @@ module ActiveRecord
36
36
  end
37
37
  end
38
38
 
39
+ # Creates an object (or multiple objects) and saves it to the database,
40
+ # if validations pass. Raises a RecordInvalid error if validations fail,
41
+ # unlike Base#create.
42
+ #
43
+ # The +attributes+ parameter can be either a Hash or an Array of Hashes.
44
+ # These describe which attributes to be created on the object, or
45
+ # multiple objects when given an Array of Hashes.
46
+ def create!(attributes = nil, &block)
47
+ if attributes.is_a?(Array)
48
+ attributes.collect { |attr| create!(attr, &block) }
49
+ else
50
+ object = new(attributes, &block)
51
+ object.save!
52
+ object
53
+ end
54
+ end
55
+
39
56
  # Given an attributes hash, +instantiate+ returns a new instance of
40
57
  # the appropriate class. Accepts only keys as strings.
41
58
  #
@@ -48,8 +65,8 @@ module ActiveRecord
48
65
  # how this "single-table" inheritance mapping is implemented.
49
66
  def instantiate(attributes, column_types = {})
50
67
  klass = discriminate_class_for_record(attributes)
51
- column_types = klass.decorate_columns(column_types.dup)
52
- klass.allocate.init_with('attributes' => attributes, 'column_types' => column_types)
68
+ attributes = klass.attributes_builder.build_from_database(attributes, column_types)
69
+ klass.allocate.init_with('attributes' => attributes, 'new_record' => false)
53
70
  end
54
71
 
55
72
  private
@@ -180,9 +197,7 @@ module ActiveRecord
180
197
  def becomes(klass)
181
198
  became = klass.new
182
199
  became.instance_variable_set("@attributes", @attributes)
183
- became.instance_variable_set("@attributes_cache", @attributes_cache)
184
- changed_attributes = @changed_attributes if defined?(@changed_attributes)
185
- became.instance_variable_set("@changed_attributes", changed_attributes || {})
200
+ became.instance_variable_set("@changed_attributes", @changed_attributes) if defined?(@changed_attributes)
186
201
  became.instance_variable_set("@new_record", new_record?)
187
202
  became.instance_variable_set("@destroyed", destroyed?)
188
203
  became.instance_variable_set("@errors", errors)
@@ -215,6 +230,8 @@ module ActiveRecord
215
230
  #
216
231
  # This method raises an +ActiveRecord::ActiveRecordError+ if the
217
232
  # attribute is marked as readonly.
233
+ #
234
+ # See also +update_column+.
218
235
  def update_attribute(name, value)
219
236
  name = name.to_s
220
237
  verify_readonly_attribute(name)
@@ -270,7 +287,8 @@ module ActiveRecord
270
287
  # This method raises an +ActiveRecord::ActiveRecordError+ when called on new
271
288
  # objects, or when at least one of the attributes is marked as readonly.
272
289
  def update_columns(attributes)
273
- raise ActiveRecordError, "cannot update on a new record object" unless persisted?
290
+ raise ActiveRecordError, "cannot update a new record" if new_record?
291
+ raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
274
292
 
275
293
  attributes.each_key do |key|
276
294
  verify_readonly_attribute(key.to_s)
@@ -395,25 +413,24 @@ module ActiveRecord
395
413
  self.class.unscoped { self.class.find(id) }
396
414
  end
397
415
 
398
- @attributes.update(fresh_object.instance_variable_get('@attributes'))
399
-
400
- @column_types = self.class.column_types
401
- @column_types_override = fresh_object.instance_variable_get('@column_types_override')
402
- @attributes_cache = {}
403
- @new_record = false
416
+ @attributes = fresh_object.instance_variable_get('@attributes')
417
+ @new_record = false
404
418
  self
405
419
  end
406
420
 
407
421
  # Saves the record with the updated_at/on attributes set to the current time.
408
422
  # Please note that no validation is performed and only the +after_touch+,
409
423
  # +after_commit+ and +after_rollback+ callbacks are executed.
410
- # If an attribute name is passed, that attribute is updated along with
411
- # updated_at/on attributes.
412
424
  #
413
- # product.touch # updates updated_at/on
414
- # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
425
+ # If attribute names are passed, they are updated along with updated_at/on
426
+ # attributes.
427
+ #
428
+ # product.touch # updates updated_at/on
429
+ # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
430
+ # product.touch(:started_at, :ended_at) # updates started_at, ended_at and updated_at/on attributes
415
431
  #
416
- # If used along with +belongs_to+ then +touch+ will invoke +touch+ method on associated object.
432
+ # If used along with +belongs_to+ then +touch+ will invoke +touch+ method on
433
+ # associated object.
417
434
  #
418
435
  # class Brake < ActiveRecord::Base
419
436
  # belongs_to :car, touch: true
@@ -432,11 +449,11 @@ module ActiveRecord
432
449
  # ball = Ball.new
433
450
  # ball.touch(:updated_at) # => raises ActiveRecordError
434
451
  #
435
- def touch(name = nil)
452
+ def touch(*names)
436
453
  raise ActiveRecordError, "cannot touch on a new record object" unless persisted?
437
454
 
438
455
  attributes = timestamp_attributes_for_update_in_model
439
- attributes << name if name
456
+ attributes.concat(names)
440
457
 
441
458
  unless attributes.empty?
442
459
  current_time = current_time_from_proper_timezone
@@ -449,7 +466,7 @@ module ActiveRecord
449
466
 
450
467
  changes[self.class.locking_column] = increment_lock if locking_enabled?
451
468
 
452
- changed_attributes.except!(*changes.keys)
469
+ clear_attribute_changes(changes.keys)
453
470
  primary_key = self.class.primary_key
454
471
  self.class.unscoped.where(primary_key => self[primary_key]).update_all(changes) == 1
455
472
  else
@@ -487,7 +504,7 @@ module ActiveRecord
487
504
 
488
505
  # Updates the associated record with values matching those of the instance attributes.
489
506
  # Returns the number of affected rows.
490
- def _update_record(attribute_names = @attributes.keys)
507
+ def _update_record(attribute_names = self.attribute_names)
491
508
  attributes_values = arel_attributes_with_values_for_update(attribute_names)
492
509
  if attributes_values.empty?
493
510
  0
@@ -498,7 +515,7 @@ module ActiveRecord
498
515
 
499
516
  # Creates a record with values matching those of the instance attributes
500
517
  # and returns its id.
501
- def _create_record(attribute_names = @attributes.keys)
518
+ def _create_record(attribute_names = self.attribute_names)
502
519
  attributes_values = arel_attributes_with_values_for_create(attribute_names)
503
520
 
504
521
  new_id = self.class.unscoped.insert attributes_values
@@ -1,4 +1,3 @@
1
-
2
1
  module ActiveRecord
3
2
  # = Active Record Query Cache
4
3
  class QueryCache
@@ -29,9 +28,10 @@ module ActiveRecord
29
28
  end
30
29
 
31
30
  def call(env)
32
- enabled = ActiveRecord::Base.connection.query_cache_enabled
31
+ connection = ActiveRecord::Base.connection
32
+ enabled = connection.query_cache_enabled
33
33
  connection_id = ActiveRecord::Base.connection_id
34
- ActiveRecord::Base.connection.enable_query_cache!
34
+ connection.enable_query_cache!
35
35
 
36
36
  response = @app.call(env)
37
37
  response[2] = Rack::BodyProxy.new(response[2]) do
@@ -37,14 +37,7 @@ module ActiveRecord
37
37
  # Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
38
38
  def find_by_sql(sql, binds = [])
39
39
  result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds)
40
- column_types = {}
41
-
42
- if result_set.respond_to? :column_types
43
- column_types = result_set.column_types
44
- else
45
- ActiveSupport::Deprecation.warn "the object returned from `select_all` must respond to `column_types`"
46
- end
47
-
40
+ column_types = result_set.column_types.except(*columns_hash.keys)
48
41
  result_set.map { |record| instantiate(record, column_types) }
49
42
  end
50
43
 
@@ -36,6 +36,8 @@ module ActiveRecord
36
36
  config.eager_load_namespaces << ActiveRecord
37
37
 
38
38
  rake_tasks do
39
+ require "active_record/base"
40
+
39
41
  namespace :db do
40
42
  task :load_config do
41
43
  ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
@@ -114,17 +116,22 @@ module ActiveRecord
114
116
  # and then establishes the connection.
115
117
  initializer "active_record.initialize_database" do |app|
116
118
  ActiveSupport.on_load(:active_record) do
119
+ self.configurations = Rails.application.config.database_configuration
117
120
 
118
- class ActiveRecord::NoDatabaseError
119
- remove_possible_method :extend_message
120
- def extend_message(message)
121
- message << "Run `$ bin/rake db:create db:migrate` to create your database"
122
- message
123
- end
124
- end
121
+ begin
122
+ establish_connection
123
+ rescue ActiveRecord::NoDatabaseError
124
+ warn <<-end_warning
125
+ Oops - You have a database configured, but it doesn't exist yet!
125
126
 
126
- self.configurations = Rails.application.config.database_configuration
127
- establish_connection
127
+ Here's how to get started:
128
+
129
+ 1. Configure your database in config/database.yml.
130
+ 2. Run `bin/rake db:create` to create the database.
131
+ 3. Run `bin/rake db:setup` to load your database schema.
132
+ end_warning
133
+ raise
134
+ end
128
135
  end
129
136
  end
130
137
 
@@ -142,8 +149,8 @@ module ActiveRecord
142
149
  ActiveSupport.on_load(:active_record) do
143
150
  ActionDispatch::Reloader.send(hook) do
144
151
  if ActiveRecord::Base.connected?
145
- ActiveRecord::Base.clear_cache!
146
152
  ActiveRecord::Base.clear_reloadable_connections!
153
+ ActiveRecord::Base.clear_cache!
147
154
  end
148
155
  end
149
156
  end
@@ -28,12 +28,20 @@ db_namespace = namespace :db do
28
28
  ActiveRecord::Tasks::DatabaseTasks.drop_current
29
29
  end
30
30
 
31
+ namespace :purge do
32
+ task :all => :load_config do
33
+ ActiveRecord::Tasks::DatabaseTasks.purge_all
34
+ end
35
+ end
36
+
37
+ # desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases."
38
+ task :purge => [:load_config] do
39
+ ActiveRecord::Tasks::DatabaseTasks.purge_current
40
+ end
41
+
31
42
  desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
32
43
  task :migrate => [:environment, :load_config] do
33
- ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
34
- ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration|
35
- ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
36
- end
44
+ ActiveRecord::Tasks::DatabaseTasks.migrate
37
45
  db_namespace['_dump'].invoke if ActiveRecord::Base.dump_schema_after_migration
38
46
  end
39
47
 
@@ -82,23 +90,21 @@ db_namespace = namespace :db do
82
90
 
83
91
  desc 'Display status of migrations'
84
92
  task :status => [:environment, :load_config] do
85
- unless ActiveRecord::Base.connection.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
86
- puts 'Schema migrations table does not exist yet.'
87
- next # means "return" for rake task
93
+ unless ActiveRecord::SchemaMigration.table_exists?
94
+ abort 'Schema migrations table does not exist yet.'
88
95
  end
89
- db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
90
- db_list.map! { |version| ActiveRecord::SchemaMigration.normalize_migration_number(version) }
91
- file_list = []
92
- ActiveRecord::Migrator.migrations_paths.each do |path|
93
- Dir.foreach(path) do |file|
94
- # match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
95
- if match_data = /^(\d{3,})_(.+)\.rb$/.match(file)
96
- version = ActiveRecord::SchemaMigration.normalize_migration_number(match_data[1])
97
- status = db_list.delete(version) ? 'up' : 'down'
98
- file_list << [status, version, match_data[2].humanize]
96
+ db_list = ActiveRecord::SchemaMigration.normalized_versions
97
+
98
+ file_list =
99
+ ActiveRecord::Migrator.migrations_paths.flat_map do |path|
100
+ # match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
101
+ Dir.foreach(path).grep(/^(\d{3,})_(.+)\.rb$/) do
102
+ version = ActiveRecord::SchemaMigration.normalize_migration_number($1)
103
+ status = db_list.delete(version) ? 'up' : 'down'
104
+ [status, version, $2.humanize]
105
+ end
99
106
  end
100
- end
101
- end
107
+
102
108
  db_list.map! do |version|
103
109
  ['up', version, '********** NO FILE **********']
104
110
  end
@@ -106,8 +112,8 @@ db_namespace = namespace :db do
106
112
  puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
107
113
  puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
108
114
  puts "-" * 50
109
- (db_list + file_list).sort_by {|migration| migration[1]}.each do |migration|
110
- puts "#{migration[0].center(8)} #{migration[1].ljust(14)} #{migration[2]}"
115
+ (db_list + file_list).sort_by { |_, version, _| version }.each do |status, version, name|
116
+ puts "#{status.center(8)} #{version.ljust(14)} #{name}"
111
117
  end
112
118
  puts
113
119
  end
@@ -179,17 +185,21 @@ db_namespace = namespace :db do
179
185
  task :load => [:environment, :load_config] do
180
186
  require 'active_record/fixtures'
181
187
 
182
- base_dir = if ENV['FIXTURES_PATH']
183
- File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
184
- else
185
- ActiveRecord::Tasks::DatabaseTasks.fixtures_path
186
- end
188
+ base_dir = ActiveRecord::Tasks::DatabaseTasks.fixtures_path
187
189
 
188
- fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
190
+ fixtures_dir = if ENV['FIXTURES_DIR']
191
+ File.join base_dir, ENV['FIXTURES_DIR']
192
+ else
193
+ base_dir
194
+ end
189
195
 
190
- (ENV['FIXTURES'] ? ENV['FIXTURES'].split(',') : Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
191
- ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_file)
192
- end
196
+ fixture_files = if ENV['FIXTURES']
197
+ ENV['FIXTURES'].split(',')
198
+ else
199
+ Pathname.glob("#{fixtures_dir}/**/*.yml").map {|f| f.basename.sub_ext('').to_s }
200
+ end
201
+
202
+ ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_files)
193
203
  end
194
204
 
195
205
  # desc "Search for a fixture given a LABEL or ID. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
@@ -201,12 +211,7 @@ db_namespace = namespace :db do
201
211
 
202
212
  puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label
203
213
 
204
- base_dir = if ENV['FIXTURES_PATH']
205
- File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
206
- else
207
- ActiveRecord::Tasks::DatabaseTasks.fixtures_path
208
- end
209
-
214
+ base_dir = ActiveRecord::Tasks::DatabaseTasks.fixtures_path
210
215
 
211
216
  Dir["#{base_dir}/**/*.yml"].each do |file|
212
217
  if data = YAML::load(ERB.new(IO.read(file)).result)
@@ -279,7 +284,7 @@ db_namespace = namespace :db do
279
284
  db_namespace['structure:dump'].reenable
280
285
  end
281
286
 
282
- # desc "Recreate the databases from the structure.sql file"
287
+ desc "Recreate the databases from the structure.sql file"
283
288
  task :load => [:environment, :load_config] do
284
289
  ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:sql, ENV['DB_STRUCTURE'])
285
290
  end
@@ -299,7 +304,7 @@ db_namespace = namespace :db do
299
304
  end
300
305
 
301
306
  # desc "Recreate the test database from the current schema"
302
- task :load => %w(db:test:purge) do
307
+ task :load => %w(db:test:deprecated db:test:purge) do
303
308
  case ActiveRecord::Base.schema_format
304
309
  when :ruby
305
310
  db_namespace["test:load_schema"].invoke
@@ -309,7 +314,7 @@ db_namespace = namespace :db do
309
314
  end
310
315
 
311
316
  # desc "Recreate the test database from an existent schema.rb file"
312
- task :load_schema => %w(db:test:purge) do
317
+ task :load_schema => %w(db:test:deprecated db:test:purge) do
313
318
  begin
314
319
  should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
315
320
  ActiveRecord::Schema.verbose = false
@@ -322,7 +327,7 @@ db_namespace = namespace :db do
322
327
  end
323
328
 
324
329
  # desc "Recreate the test database from an existent structure.sql file"
325
- task :load_structure => %w(db:test:purge) do
330
+ task :load_structure => %w(db:test:deprecated db:test:purge) do
326
331
  ActiveRecord::Tasks::DatabaseTasks.load_schema_for ActiveRecord::Base.configurations['test'], :sql, ENV['SCHEMA']
327
332
  end
328
333
 
@@ -343,12 +348,12 @@ db_namespace = namespace :db do
343
348
  task :clone_structure => %w(db:test:deprecated db:structure:dump db:test:load_structure)
344
349
 
345
350
  # desc "Empty the test database"
346
- task :purge => %w(environment load_config) do
351
+ task :purge => %w(db:test:deprecated environment load_config) do
347
352
  ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
348
353
  end
349
354
 
350
355
  # desc 'Check for pending migrations and load the test schema'
351
- task :prepare => %w(environment load_config) do
356
+ task :prepare => %w(db:test:deprecated environment load_config) do
352
357
  unless ActiveRecord::Base.configurations.blank?
353
358
  db_namespace['test:load'].invoke
354
359
  end