activerecord 4.0.4 → 4.1.16
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1632 -1797
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/examples/performance.rb +30 -18
- data/examples/simple.rb +4 -4
- data/lib/active_record/aggregations.rb +2 -1
- data/lib/active_record/association_relation.rb +4 -0
- data/lib/active_record/associations/alias_tracker.rb +49 -29
- data/lib/active_record/associations/association.rb +9 -17
- data/lib/active_record/associations/association_scope.rb +59 -49
- data/lib/active_record/associations/belongs_to_association.rb +34 -25
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +6 -1
- data/lib/active_record/associations/builder/association.rb +84 -54
- data/lib/active_record/associations/builder/belongs_to.rb +90 -58
- data/lib/active_record/associations/builder/collection_association.rb +47 -45
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +119 -25
- data/lib/active_record/associations/builder/has_many.rb +3 -3
- data/lib/active_record/associations/builder/has_one.rb +5 -7
- data/lib/active_record/associations/builder/singular_association.rb +6 -7
- data/lib/active_record/associations/collection_association.rb +121 -111
- data/lib/active_record/associations/collection_proxy.rb +73 -18
- data/lib/active_record/associations/has_many_association.rb +14 -11
- data/lib/active_record/associations/has_many_through_association.rb +33 -6
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +46 -104
- data/lib/active_record/associations/join_dependency/join_base.rb +6 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +18 -37
- data/lib/active_record/associations/join_dependency.rb +208 -168
- data/lib/active_record/associations/preloader/association.rb +69 -27
- data/lib/active_record/associations/preloader/collection_association.rb +2 -2
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/singular_association.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +58 -26
- data/lib/active_record/associations/preloader.rb +63 -49
- data/lib/active_record/associations/singular_association.rb +6 -5
- data/lib/active_record/associations/through_association.rb +30 -9
- data/lib/active_record/associations.rb +116 -42
- data/lib/active_record/attribute_assignment.rb +6 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -1
- data/lib/active_record/attribute_methods/dirty.rb +35 -26
- data/lib/active_record/attribute_methods/primary_key.rb +8 -1
- data/lib/active_record/attribute_methods/read.rb +56 -29
- data/lib/active_record/attribute_methods/serialization.rb +44 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +13 -1
- data/lib/active_record/attribute_methods/write.rb +59 -26
- data/lib/active_record/attribute_methods.rb +82 -43
- data/lib/active_record/autosave_association.rb +209 -194
- data/lib/active_record/base.rb +6 -2
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/json.rb +13 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +5 -10
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +14 -24
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -13
- data/lib/active_record/connection_adapters/abstract/quoting.rb +6 -3
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +90 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -8
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +45 -70
- data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +28 -96
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +74 -66
- data/lib/active_record/connection_adapters/column.rb +1 -35
- data/lib/active_record/connection_adapters/connection_specification.rb +231 -43
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +10 -5
- data/lib/active_record/connection_adapters/mysql_adapter.rb +24 -17
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +22 -15
- data/lib/active_record/connection_adapters/postgresql/cast.rb +12 -4
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -44
- data/lib/active_record/connection_adapters/postgresql/oid.rb +38 -14
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +37 -12
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +20 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +98 -52
- data/lib/active_record/connection_adapters/schema_cache.rb +8 -29
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +55 -60
- data/lib/active_record/connection_handling.rb +39 -5
- data/lib/active_record/core.rb +38 -54
- data/lib/active_record/counter_cache.rb +9 -10
- data/lib/active_record/dynamic_matchers.rb +6 -2
- data/lib/active_record/enum.rb +199 -0
- data/lib/active_record/errors.rb +22 -5
- data/lib/active_record/fixture_set/file.rb +2 -1
- data/lib/active_record/fixtures.rb +173 -76
- data/lib/active_record/gem_version.rb +15 -0
- data/lib/active_record/inheritance.rb +23 -9
- data/lib/active_record/integration.rb +54 -1
- data/lib/active_record/locking/optimistic.rb +7 -2
- data/lib/active_record/locking/pessimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +6 -13
- data/lib/active_record/migration/command_recorder.rb +8 -2
- data/lib/active_record/migration.rb +91 -56
- data/lib/active_record/model_schema.rb +7 -14
- data/lib/active_record/nested_attributes.rb +25 -13
- data/lib/active_record/no_touching.rb +52 -0
- data/lib/active_record/null_relation.rb +26 -6
- data/lib/active_record/persistence.rb +23 -29
- data/lib/active_record/querying.rb +15 -12
- data/lib/active_record/railtie.rb +12 -61
- data/lib/active_record/railties/databases.rake +37 -56
- data/lib/active_record/readonly_attributes.rb +0 -6
- data/lib/active_record/reflection.rb +230 -79
- data/lib/active_record/relation/batches.rb +74 -24
- data/lib/active_record/relation/calculations.rb +52 -48
- data/lib/active_record/relation/delegation.rb +54 -39
- data/lib/active_record/relation/finder_methods.rb +210 -67
- data/lib/active_record/relation/merger.rb +15 -12
- data/lib/active_record/relation/predicate_builder/array_handler.rb +29 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder.rb +81 -40
- data/lib/active_record/relation/query_methods.rb +185 -108
- data/lib/active_record/relation/spawn_methods.rb +8 -5
- data/lib/active_record/relation.rb +79 -84
- data/lib/active_record/result.rb +45 -6
- data/lib/active_record/runtime_registry.rb +5 -0
- data/lib/active_record/sanitization.rb +4 -4
- data/lib/active_record/schema_dumper.rb +18 -6
- data/lib/active_record/schema_migration.rb +31 -18
- data/lib/active_record/scoping/default.rb +5 -18
- data/lib/active_record/scoping/named.rb +14 -29
- data/lib/active_record/scoping.rb +5 -0
- data/lib/active_record/store.rb +67 -18
- data/lib/active_record/tasks/database_tasks.rb +66 -26
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -10
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
- data/lib/active_record/timestamp.rb +6 -6
- data/lib/active_record/transactions.rb +10 -12
- data/lib/active_record/validations/presence.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +19 -9
- data/lib/active_record/version.rb +4 -7
- data/lib/active_record.rb +5 -7
- data/lib/rails/generators/active_record/migration/migration_generator.rb +4 -0
- data/lib/rails/generators/active_record/migration.rb +18 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +4 -0
- data/lib/rails/generators/active_record.rb +2 -8
- metadata +18 -30
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -65
- data/lib/active_record/associations/join_helper.rb +0 -45
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- data/lib/active_record/tasks/firebird_database_tasks.rb +0 -56
- data/lib/active_record/tasks/oracle_database_tasks.rb +0 -45
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +0 -48
- data/lib/active_record/test_case.rb +0 -96
@@ -37,7 +37,7 @@ module ActiveRecord
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# Given an attributes hash, +instantiate+ returns a new instance of
|
40
|
-
# the appropriate class.
|
40
|
+
# the appropriate class. Accepts only keys as strings.
|
41
41
|
#
|
42
42
|
# For example, +Post.all+ may return Comments, Messages, and Emails
|
43
43
|
# by storing the record's subclass in a +type+ attribute. By calling
|
@@ -46,10 +46,10 @@ module ActiveRecord
|
|
46
46
|
#
|
47
47
|
# See +ActiveRecord::Inheritance#discriminate_class_for_record+ to see
|
48
48
|
# how this "single-table" inheritance mapping is implemented.
|
49
|
-
def instantiate(
|
50
|
-
klass = discriminate_class_for_record(
|
49
|
+
def instantiate(attributes, column_types = {})
|
50
|
+
klass = discriminate_class_for_record(attributes)
|
51
51
|
column_types = klass.decorate_columns(column_types.dup)
|
52
|
-
klass.allocate.init_with('attributes' =>
|
52
|
+
klass.allocate.init_with('attributes' => attributes, 'column_types' => column_types)
|
53
53
|
end
|
54
54
|
|
55
55
|
private
|
@@ -181,6 +181,8 @@ module ActiveRecord
|
|
181
181
|
became = klass.new
|
182
182
|
became.instance_variable_set("@attributes", @attributes)
|
183
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 || {})
|
184
186
|
became.instance_variable_set("@new_record", new_record?)
|
185
187
|
became.instance_variable_set("@destroyed", destroyed?)
|
186
188
|
became.instance_variable_set("@errors", errors)
|
@@ -268,7 +270,7 @@ module ActiveRecord
|
|
268
270
|
# This method raises an +ActiveRecord::ActiveRecordError+ when called on new
|
269
271
|
# objects, or when at least one of the attributes is marked as readonly.
|
270
272
|
def update_columns(attributes)
|
271
|
-
raise ActiveRecordError, "
|
273
|
+
raise ActiveRecordError, "cannot update on a new record object" unless persisted?
|
272
274
|
|
273
275
|
attributes.each_key do |key|
|
274
276
|
verify_readonly_attribute(key.to_s)
|
@@ -346,7 +348,8 @@ module ActiveRecord
|
|
346
348
|
# # Account Load (1.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT 1 [["id", 1]]
|
347
349
|
# # => #<Account id: 1, email: 'account@example.com'>
|
348
350
|
#
|
349
|
-
# Attributes are
|
351
|
+
# Attributes are reloaded from the database, and caches busted, in
|
352
|
+
# particular the associations cache.
|
350
353
|
#
|
351
354
|
# If the record no longer exists in the database <tt>ActiveRecord::RecordNotFound</tt>
|
352
355
|
# is raised. Otherwise, in addition to the in-place modification the method
|
@@ -364,7 +367,7 @@ module ActiveRecord
|
|
364
367
|
# assert_equal 25, account.credit # check it is updated in memory
|
365
368
|
# assert_equal 25, account.reload.credit # check it is also persisted
|
366
369
|
#
|
367
|
-
# Another
|
370
|
+
# Another common use case is optimistic locking handling:
|
368
371
|
#
|
369
372
|
# def with_optimistic_retry
|
370
373
|
# begin
|
@@ -397,12 +400,13 @@ module ActiveRecord
|
|
397
400
|
@column_types = self.class.column_types
|
398
401
|
@column_types_override = fresh_object.instance_variable_get('@column_types_override')
|
399
402
|
@attributes_cache = {}
|
403
|
+
@new_record = false
|
400
404
|
self
|
401
405
|
end
|
402
406
|
|
403
407
|
# Saves the record with the updated_at/on attributes set to the current time.
|
404
|
-
# Please note that no validation is performed and only the +after_touch
|
405
|
-
#
|
408
|
+
# Please note that no validation is performed and only the +after_touch+,
|
409
|
+
# +after_commit+ and +after_rollback+ callbacks are executed.
|
406
410
|
# If an attribute name is passed, that attribute is updated along with
|
407
411
|
# updated_at/on attributes.
|
408
412
|
#
|
@@ -429,7 +433,7 @@ module ActiveRecord
|
|
429
433
|
# ball.touch(:updated_at) # => raises ActiveRecordError
|
430
434
|
#
|
431
435
|
def touch(name = nil)
|
432
|
-
raise ActiveRecordError, "
|
436
|
+
raise ActiveRecordError, "cannot touch on a new record object" unless persisted?
|
433
437
|
|
434
438
|
attributes = timestamp_attributes_for_update_in_model
|
435
439
|
attributes << name if name
|
@@ -445,9 +449,11 @@ module ActiveRecord
|
|
445
449
|
|
446
450
|
changes[self.class.locking_column] = increment_lock if locking_enabled?
|
447
451
|
|
448
|
-
|
452
|
+
changed_attributes.except!(*changes.keys)
|
449
453
|
primary_key = self.class.primary_key
|
450
454
|
self.class.unscoped.where(primary_key => self[primary_key]).update_all(changes) == 1
|
455
|
+
else
|
456
|
+
true
|
451
457
|
end
|
452
458
|
end
|
453
459
|
|
@@ -475,36 +481,24 @@ module ActiveRecord
|
|
475
481
|
|
476
482
|
def create_or_update
|
477
483
|
raise ReadOnlyRecord if readonly?
|
478
|
-
result = new_record? ?
|
484
|
+
result = new_record? ? _create_record : _update_record
|
479
485
|
result != false
|
480
486
|
end
|
481
487
|
|
482
488
|
# Updates the associated record with values matching those of the instance attributes.
|
483
489
|
# Returns the number of affected rows.
|
484
|
-
def
|
485
|
-
|
486
|
-
if
|
490
|
+
def _update_record(attribute_names = @attributes.keys)
|
491
|
+
attributes_values = arel_attributes_with_values_for_update(attribute_names)
|
492
|
+
if attributes_values.empty?
|
487
493
|
0
|
488
494
|
else
|
489
|
-
|
490
|
-
column_hash = klass.connection.schema_cache.columns_hash klass.table_name
|
491
|
-
db_columns_with_values = attributes_with_values.map { |attr,value|
|
492
|
-
real_column = column_hash[attr.name]
|
493
|
-
[real_column, value]
|
494
|
-
}
|
495
|
-
bind_attrs = attributes_with_values.dup
|
496
|
-
bind_attrs.keys.each_with_index do |column, i|
|
497
|
-
real_column = db_columns_with_values[i].first
|
498
|
-
bind_attrs[column] = klass.connection.substitute_at(real_column, i)
|
499
|
-
end
|
500
|
-
stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id_was || id)).arel.compile_update(bind_attrs)
|
501
|
-
klass.connection.update stmt, 'SQL', db_columns_with_values
|
495
|
+
self.class.unscoped._update_record attributes_values, id, id_was
|
502
496
|
end
|
503
497
|
end
|
504
498
|
|
505
499
|
# Creates a record with values matching those of the instance attributes
|
506
500
|
# and returns its id.
|
507
|
-
def
|
501
|
+
def _create_record(attribute_names = @attributes.keys)
|
508
502
|
attributes_values = arel_attributes_with_values_for_create(attribute_names)
|
509
503
|
|
510
504
|
new_id = self.class.unscoped.insert attributes_values
|
@@ -1,20 +1,22 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Querying
|
3
|
-
delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :
|
4
|
-
delegate :
|
5
|
-
delegate :
|
6
|
-
delegate :
|
7
|
-
delegate :
|
8
|
-
delegate :
|
3
|
+
delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, to: :all
|
4
|
+
delegate :second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!, :forty_two, :forty_two!, to: :all
|
5
|
+
delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
|
6
|
+
delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
|
7
|
+
delegate :find_by, :find_by!, to: :all
|
8
|
+
delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, to: :all
|
9
|
+
delegate :find_each, :find_in_batches, to: :all
|
9
10
|
delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins,
|
10
|
-
:where, :preload, :eager_load, :includes, :from, :lock, :readonly,
|
11
|
-
:having, :create_with, :uniq, :distinct, :references, :none, :unscope, :
|
12
|
-
delegate :count, :average, :minimum, :maximum, :sum, :calculate, :
|
11
|
+
:where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly,
|
12
|
+
:having, :create_with, :uniq, :distinct, :references, :none, :unscope, to: :all
|
13
|
+
delegate :count, :average, :minimum, :maximum, :sum, :calculate, to: :all
|
14
|
+
delegate :pluck, :ids, to: :all
|
13
15
|
|
14
16
|
# Executes a custom SQL query against your database and returns all the results. The results will
|
15
17
|
# be returned as an array with columns requested encapsulated as attributes of the model you call
|
16
18
|
# this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
|
17
|
-
# a Product object with the attributes you specified in the SQL query.
|
19
|
+
# a +Product+ object with the attributes you specified in the SQL query.
|
18
20
|
#
|
19
21
|
# If you call a complicated SQL query which spans multiple tables the columns specified by the
|
20
22
|
# SELECT will be attributes of the model, whether or not they are columns of the corresponding
|
@@ -29,9 +31,10 @@ module ActiveRecord
|
|
29
31
|
# Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
|
30
32
|
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
|
31
33
|
#
|
32
|
-
#
|
34
|
+
# You can use the same string replacement techniques as you can with <tt>ActiveRecord::QueryMethods#where</tt>:
|
35
|
+
#
|
33
36
|
# Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
|
34
|
-
#
|
37
|
+
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
|
35
38
|
def find_by_sql(sql, binds = [])
|
36
39
|
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds)
|
37
40
|
column_types = {}
|
@@ -31,22 +31,14 @@ module ActiveRecord
|
|
31
31
|
|
32
32
|
|
33
33
|
config.active_record.use_schema_cache_dump = true
|
34
|
+
config.active_record.maintain_test_schema = true
|
34
35
|
|
35
36
|
config.eager_load_namespaces << ActiveRecord
|
36
37
|
|
37
38
|
rake_tasks do
|
38
|
-
require "active_record/base"
|
39
|
-
|
40
|
-
ActiveRecord::Tasks::DatabaseTasks.seed_loader = Rails.application
|
41
|
-
ActiveRecord::Tasks::DatabaseTasks.env = Rails.env
|
42
|
-
|
43
39
|
namespace :db do
|
44
40
|
task :load_config do
|
45
|
-
ActiveRecord::Tasks::DatabaseTasks.db_dir = Rails.application.config.paths["db"].first
|
46
41
|
ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
|
47
|
-
ActiveRecord::Tasks::DatabaseTasks.migrations_paths = Rails.application.paths['db/migrate'].to_a
|
48
|
-
ActiveRecord::Tasks::DatabaseTasks.fixtures_path = File.join Rails.root, 'test', 'fixtures'
|
49
|
-
ActiveRecord::Tasks::DatabaseTasks.root = Rails.root
|
50
42
|
|
51
43
|
if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
|
52
44
|
if engine.paths['db/migrate'].existent
|
@@ -112,56 +104,6 @@ module ActiveRecord
|
|
112
104
|
|
113
105
|
initializer "active_record.set_configs" do |app|
|
114
106
|
ActiveSupport.on_load(:active_record) do
|
115
|
-
begin
|
116
|
-
old_behavior, ActiveSupport::Deprecation.behavior = ActiveSupport::Deprecation.behavior, :stderr
|
117
|
-
whitelist_attributes = app.config.active_record.delete(:whitelist_attributes)
|
118
|
-
|
119
|
-
if respond_to?(:mass_assignment_sanitizer=)
|
120
|
-
mass_assignment_sanitizer = nil
|
121
|
-
else
|
122
|
-
mass_assignment_sanitizer = app.config.active_record.delete(:mass_assignment_sanitizer)
|
123
|
-
end
|
124
|
-
|
125
|
-
unless whitelist_attributes.nil? && mass_assignment_sanitizer.nil?
|
126
|
-
ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
|
127
|
-
Model based mass assignment security has been extracted
|
128
|
-
out of Rails into a gem. Please use the new recommended protection model for
|
129
|
-
params or add `protected_attributes` to your Gemfile to use the old one.
|
130
|
-
|
131
|
-
To disable this message remove the `whitelist_attributes` option from your
|
132
|
-
`config/application.rb` file and any `mass_assignment_sanitizer` options
|
133
|
-
from your `config/environments/*.rb` files.
|
134
|
-
|
135
|
-
See http://guides.rubyonrails.org/security.html#mass-assignment for more information.
|
136
|
-
EOF
|
137
|
-
end
|
138
|
-
|
139
|
-
unless app.config.active_record.delete(:auto_explain_threshold_in_seconds).nil?
|
140
|
-
ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
|
141
|
-
The Active Record auto explain feature has been removed.
|
142
|
-
|
143
|
-
To disable this message remove the `active_record.auto_explain_threshold_in_seconds`
|
144
|
-
option from the `config/environments/*.rb` config file.
|
145
|
-
|
146
|
-
See http://guides.rubyonrails.org/4_0_release_notes.html for more information.
|
147
|
-
EOF
|
148
|
-
end
|
149
|
-
|
150
|
-
unless app.config.active_record.delete(:observers).nil?
|
151
|
-
ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
|
152
|
-
Active Record Observers has been extracted out of Rails into a gem.
|
153
|
-
Please use callbacks or add `rails-observers` to your Gemfile to use observers.
|
154
|
-
|
155
|
-
To disable this message remove the `observers` option from your
|
156
|
-
`config/application.rb` or from your initializers.
|
157
|
-
|
158
|
-
See http://guides.rubyonrails.org/4_0_release_notes.html for more information.
|
159
|
-
EOF
|
160
|
-
end
|
161
|
-
ensure
|
162
|
-
ActiveSupport::Deprecation.behavior = old_behavior
|
163
|
-
end
|
164
|
-
|
165
107
|
app.config.active_record.each do |k,v|
|
166
108
|
send "#{k}=", v
|
167
109
|
end
|
@@ -172,7 +114,16 @@ module ActiveRecord
|
|
172
114
|
# and then establishes the connection.
|
173
115
|
initializer "active_record.initialize_database" do |app|
|
174
116
|
ActiveSupport.on_load(:active_record) do
|
175
|
-
|
117
|
+
|
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
|
125
|
+
|
126
|
+
self.configurations = Rails.application.config.database_configuration
|
176
127
|
establish_connection
|
177
128
|
end
|
178
129
|
end
|
@@ -191,8 +142,8 @@ module ActiveRecord
|
|
191
142
|
ActiveSupport.on_load(:active_record) do
|
192
143
|
ActionDispatch::Reloader.send(hook) do
|
193
144
|
if ActiveRecord::Base.connected?
|
194
|
-
ActiveRecord::Base.clear_reloadable_connections!
|
195
145
|
ActiveRecord::Base.clear_cache!
|
146
|
+
ActiveRecord::Base.clear_reloadable_connections!
|
196
147
|
end
|
197
148
|
end
|
198
149
|
end
|
@@ -2,7 +2,7 @@ require 'active_record'
|
|
2
2
|
|
3
3
|
db_namespace = namespace :db do
|
4
4
|
task :load_config do
|
5
|
-
ActiveRecord::Base.configurations
|
5
|
+
ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
|
6
6
|
ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
|
7
7
|
end
|
8
8
|
|
@@ -12,13 +12,9 @@ db_namespace = namespace :db do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
desc '
|
15
|
+
desc 'Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV it defaults to creating the development and test databases.'
|
16
16
|
task :create => [:load_config] do
|
17
|
-
|
18
|
-
ActiveRecord::Tasks::DatabaseTasks.create_database_url
|
19
|
-
else
|
20
|
-
ActiveRecord::Tasks::DatabaseTasks.create_current
|
21
|
-
end
|
17
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current
|
22
18
|
end
|
23
19
|
|
24
20
|
namespace :drop do
|
@@ -27,13 +23,9 @@ db_namespace = namespace :db do
|
|
27
23
|
end
|
28
24
|
end
|
29
25
|
|
30
|
-
desc 'Drops the database
|
26
|
+
desc 'Drops 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 dropping the development and test databases.'
|
31
27
|
task :drop => [:load_config] do
|
32
|
-
|
33
|
-
ActiveRecord::Tasks::DatabaseTasks.drop_database_url
|
34
|
-
else
|
35
|
-
ActiveRecord::Tasks::DatabaseTasks.drop_current
|
36
|
-
end
|
28
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_current
|
37
29
|
end
|
38
30
|
|
39
31
|
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
@@ -42,7 +34,7 @@ db_namespace = namespace :db do
|
|
42
34
|
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration|
|
43
35
|
ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
|
44
36
|
end
|
45
|
-
db_namespace['_dump'].invoke
|
37
|
+
db_namespace['_dump'].invoke if ActiveRecord::Base.dump_schema_after_migration
|
46
38
|
end
|
47
39
|
|
48
40
|
task :_dump do
|
@@ -83,7 +75,7 @@ db_namespace = namespace :db do
|
|
83
75
|
# desc 'Runs the "down" for a given migration VERSION.'
|
84
76
|
task :down => [:environment, :load_config] do
|
85
77
|
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
86
|
-
raise 'VERSION is required' unless version
|
78
|
+
raise 'VERSION is required - To go down one migration, run db:rollback' unless version
|
87
79
|
ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_paths, version)
|
88
80
|
db_namespace['_dump'].invoke
|
89
81
|
end
|
@@ -95,14 +87,15 @@ db_namespace = namespace :db do
|
|
95
87
|
next # means "return" for rake task
|
96
88
|
end
|
97
89
|
db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
|
98
|
-
db_list.map! { |version|
|
90
|
+
db_list.map! { |version| ActiveRecord::SchemaMigration.normalize_migration_number(version) }
|
99
91
|
file_list = []
|
100
92
|
ActiveRecord::Migrator.migrations_paths.each do |path|
|
101
93
|
Dir.foreach(path) do |file|
|
102
94
|
# match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
|
103
95
|
if match_data = /^(\d{3,})_(.+)\.rb$/.match(file)
|
104
|
-
|
105
|
-
|
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]
|
106
99
|
end
|
107
100
|
end
|
108
101
|
end
|
@@ -172,7 +165,7 @@ db_namespace = namespace :db do
|
|
172
165
|
end
|
173
166
|
end
|
174
167
|
|
175
|
-
desc 'Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the
|
168
|
+
desc 'Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the database first)'
|
176
169
|
task :setup => ['db:schema:load_if_ruby', 'db:structure:load_if_sql', :seed]
|
177
170
|
|
178
171
|
desc 'Load the seed data from db/seeds.rb'
|
@@ -187,9 +180,6 @@ db_namespace = namespace :db do
|
|
187
180
|
require 'active_record/fixtures'
|
188
181
|
|
189
182
|
base_dir = if ENV['FIXTURES_PATH']
|
190
|
-
STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " +
|
191
|
-
"ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " +
|
192
|
-
"instead."
|
193
183
|
File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
|
194
184
|
else
|
195
185
|
ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
@@ -197,7 +187,7 @@ db_namespace = namespace :db do
|
|
197
187
|
|
198
188
|
fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
|
199
189
|
|
200
|
-
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(
|
190
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(',') : Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
|
201
191
|
ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_file)
|
202
192
|
end
|
203
193
|
end
|
@@ -212,9 +202,6 @@ db_namespace = namespace :db do
|
|
212
202
|
puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label
|
213
203
|
|
214
204
|
base_dir = if ENV['FIXTURES_PATH']
|
215
|
-
STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " +
|
216
|
-
"ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " +
|
217
|
-
"instead."
|
218
205
|
File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
|
219
206
|
else
|
220
207
|
ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
@@ -236,7 +223,7 @@ db_namespace = namespace :db do
|
|
236
223
|
end
|
237
224
|
|
238
225
|
namespace :schema do
|
239
|
-
desc 'Create a db/schema.rb file that
|
226
|
+
desc 'Create a db/schema.rb file that is portable against any DB supported by AR'
|
240
227
|
task :dump => [:environment, :load_config] do
|
241
228
|
require 'active_record/schema_dumper'
|
242
229
|
filename = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb')
|
@@ -248,12 +235,7 @@ db_namespace = namespace :db do
|
|
248
235
|
|
249
236
|
desc 'Load a schema.rb file into the database'
|
250
237
|
task :load => [:environment, :load_config] do
|
251
|
-
|
252
|
-
if File.exist?(file)
|
253
|
-
load(file)
|
254
|
-
else
|
255
|
-
abort %{#{file} doesn't exist yet. Run `rake db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.}
|
256
|
-
end
|
238
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:ruby, ENV['SCHEMA'])
|
257
239
|
end
|
258
240
|
|
259
241
|
task :load_if_ruby => ['db:create', :environment] do
|
@@ -287,9 +269,11 @@ db_namespace = namespace :db do
|
|
287
269
|
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
288
270
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
|
289
271
|
|
290
|
-
if ActiveRecord::Base.connection.supports_migrations?
|
272
|
+
if ActiveRecord::Base.connection.supports_migrations? &&
|
273
|
+
ActiveRecord::SchemaMigration.table_exists?
|
291
274
|
File.open(filename, "a") do |f|
|
292
275
|
f.puts ActiveRecord::Base.connection.dump_schema_information
|
276
|
+
f.print "\n"
|
293
277
|
end
|
294
278
|
end
|
295
279
|
db_namespace['structure:dump'].reenable
|
@@ -297,9 +281,7 @@ db_namespace = namespace :db do
|
|
297
281
|
|
298
282
|
# desc "Recreate the databases from the structure.sql file"
|
299
283
|
task :load => [:environment, :load_config] do
|
300
|
-
|
301
|
-
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
302
|
-
ActiveRecord::Tasks::DatabaseTasks.structure_load(current_config, filename)
|
284
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:sql, ENV['DB_STRUCTURE'])
|
303
285
|
end
|
304
286
|
|
305
287
|
task :load_if_sql => ['db:create', :environment] do
|
@@ -309,8 +291,15 @@ db_namespace = namespace :db do
|
|
309
291
|
|
310
292
|
namespace :test do
|
311
293
|
|
294
|
+
task :deprecated do
|
295
|
+
Rake.application.top_level_tasks.grep(/^db:test:/).each do |task|
|
296
|
+
$stderr.puts "WARNING: #{task} is deprecated. The Rails test helper now maintains " \
|
297
|
+
"your test schema automatically, see the release notes for details."
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
312
301
|
# desc "Recreate the test database from the current schema"
|
313
|
-
task :load =>
|
302
|
+
task :load => %w(db:test:purge) do
|
314
303
|
case ActiveRecord::Base.schema_format
|
315
304
|
when :ruby
|
316
305
|
db_namespace["test:load_schema"].invoke
|
@@ -320,12 +309,11 @@ db_namespace = namespace :db do
|
|
320
309
|
end
|
321
310
|
|
322
311
|
# desc "Recreate the test database from an existent schema.rb file"
|
323
|
-
task :load_schema =>
|
312
|
+
task :load_schema => %w(db:test:purge) do
|
324
313
|
begin
|
325
314
|
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
326
|
-
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
|
327
315
|
ActiveRecord::Schema.verbose = false
|
328
|
-
|
316
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_for ActiveRecord::Base.configurations['test'], :ruby, ENV['SCHEMA']
|
329
317
|
ensure
|
330
318
|
if should_reconnect
|
331
319
|
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ActiveRecord::Tasks::DatabaseTasks.env])
|
@@ -334,17 +322,12 @@ db_namespace = namespace :db do
|
|
334
322
|
end
|
335
323
|
|
336
324
|
# desc "Recreate the test database from an existent structure.sql file"
|
337
|
-
task :load_structure =>
|
338
|
-
|
339
|
-
ActiveRecord::Tasks::DatabaseTasks.current_config(:config => ActiveRecord::Base.configurations['test'])
|
340
|
-
db_namespace["structure:load"].invoke
|
341
|
-
ensure
|
342
|
-
ActiveRecord::Tasks::DatabaseTasks.current_config(:config => nil)
|
343
|
-
end
|
325
|
+
task :load_structure => %w(db:test:purge) do
|
326
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_for ActiveRecord::Base.configurations['test'], :sql, ENV['SCHEMA']
|
344
327
|
end
|
345
328
|
|
346
329
|
# desc "Recreate the test database from a fresh schema"
|
347
|
-
task :clone => :environment do
|
330
|
+
task :clone => %w(db:test:deprecated environment) do
|
348
331
|
case ActiveRecord::Base.schema_format
|
349
332
|
when :ruby
|
350
333
|
db_namespace["test:clone_schema"].invoke
|
@@ -354,18 +337,18 @@ db_namespace = namespace :db do
|
|
354
337
|
end
|
355
338
|
|
356
339
|
# desc "Recreate the test database from a fresh schema.rb file"
|
357
|
-
task :clone_schema =>
|
340
|
+
task :clone_schema => %w(db:test:deprecated db:schema:dump db:test:load_schema)
|
358
341
|
|
359
342
|
# desc "Recreate the test database from a fresh structure.sql file"
|
360
|
-
task :clone_structure =>
|
343
|
+
task :clone_structure => %w(db:test:deprecated db:structure:dump db:test:load_structure)
|
361
344
|
|
362
345
|
# desc "Empty the test database"
|
363
|
-
task :purge =>
|
346
|
+
task :purge => %w(environment load_config) do
|
364
347
|
ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
|
365
348
|
end
|
366
349
|
|
367
350
|
# desc 'Check for pending migrations and load the test schema'
|
368
|
-
task :prepare =>
|
351
|
+
task :prepare => %w(environment load_config) do
|
369
352
|
unless ActiveRecord::Base.configurations.blank?
|
370
353
|
db_namespace['test:load'].invoke
|
371
354
|
end
|
@@ -379,7 +362,7 @@ namespace :railties do
|
|
379
362
|
task :migrations => :'db:load_config' do
|
380
363
|
to_load = ENV['FROM'].blank? ? :all : ENV['FROM'].split(",").map {|n| n.strip }
|
381
364
|
railties = {}
|
382
|
-
Rails.application.
|
365
|
+
Rails.application.migration_railties.each do |railtie|
|
383
366
|
next unless to_load == :all || to_load.include?(railtie.railtie_name)
|
384
367
|
|
385
368
|
if railtie.respond_to?(:paths) && (path = railtie.paths['db/migrate'].first)
|
@@ -400,5 +383,3 @@ namespace :railties do
|
|
400
383
|
end
|
401
384
|
end
|
402
385
|
end
|
403
|
-
|
404
|
-
task 'test:prepare' => ['db:test:prepare', 'db:test:load', 'db:abort_if_pending_migrations']
|
@@ -20,11 +20,5 @@ module ActiveRecord
|
|
20
20
|
self._attr_readonly
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
24
|
-
def _attr_readonly
|
25
|
-
message = "Instance level _attr_readonly method is deprecated, please use class level method."
|
26
|
-
ActiveSupport::Deprecation.warn message
|
27
|
-
defined?(@_attr_readonly) ? @_attr_readonly : self.class._attr_readonly
|
28
|
-
end
|
29
23
|
end
|
30
24
|
end
|