activerecord 5.0.2 → 5.0.3
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 +39 -0
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +36 -44
- data/lib/active_record/associations/collection_proxy.rb +33 -13
- data/lib/active_record/associations/has_many_association.rb +1 -7
- data/lib/active_record/associations/has_many_through_association.rb +1 -5
- data/lib/active_record/collection_cache_key.rb +16 -6
- data/lib/active_record/connection_adapters/abstract/quoting.rb +8 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +3 -7
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +2 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +8 -7
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +12 -12
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +13 -13
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +4 -4
- data/lib/active_record/explain.rb +20 -9
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/log_subscriber.rb +18 -15
- data/lib/active_record/migration.rb +25 -7
- data/lib/active_record/persistence.rb +23 -8
- data/lib/active_record/railties/databases.rake +7 -19
- data/lib/active_record/relation/calculations.rb +1 -1
- data/lib/active_record/relation/delegation.rb +2 -0
- data/lib/active_record/tasks/database_tasks.rb +2 -0
- data/lib/active_record/transactions.rb +1 -1
- data/lib/rails/generators/active_record/migration.rb +8 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +0 -8
- data/lib/rails/generators/active_record/model/model_generator.rb +0 -8
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2aa37fd1fc57e36d5f14ee9009cf6ba7ec6b601
|
4
|
+
data.tar.gz: c974b336ea71a782c1381d480c0ef2687dfc32c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f27b1ef2da04f68ac793b7039dc8ff8e0c78d8cf8db60d0b554f00174882b025d41dde0a4ad1a86ad5dad95c9facd826852b398c666968965cb54154d7f27cc6
|
7
|
+
data.tar.gz: e792934d6d1a39b07fef4cbff53969729f292edab3e23ea33231ba087b23d7e8a3eed648135fa45fc4e023dc8c217e7260753f3d69defeca3ecf0e21cabe804c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,42 @@
|
|
1
|
+
* Check whether `Rails.application` defined before calling it
|
2
|
+
|
3
|
+
In #27674 we changed the migration generator to generate migrations at the
|
4
|
+
path defined in `Rails.application.config.paths` however the code checked
|
5
|
+
for the presence of the `Rails` constant but not the `Rails.application`
|
6
|
+
method which caused problems when using Active Record and generators outside
|
7
|
+
of the context of a Rails application.
|
8
|
+
|
9
|
+
Fixes #28325.
|
10
|
+
|
11
|
+
* Fix `deserialize` with JSON array.
|
12
|
+
|
13
|
+
Fixes #28285.
|
14
|
+
|
15
|
+
*Ryuta Kamizono*
|
16
|
+
|
17
|
+
* Fix `rake db:schema:load` with subdirectories.
|
18
|
+
|
19
|
+
*Ryuta Kamizono*
|
20
|
+
|
21
|
+
* Fix `rake db:migrate:status` with subdirectories.
|
22
|
+
|
23
|
+
*Ryuta Kamizono*
|
24
|
+
|
25
|
+
* Don't share options between reference id and type columns
|
26
|
+
|
27
|
+
When using a polymorphic reference column in a migration, sharing options
|
28
|
+
between the two columns doesn't make sense since they are different types.
|
29
|
+
The `reference_id` column is usually an integer and the `reference_type`
|
30
|
+
column a string so options like `unsigned: true` will result in an invalid
|
31
|
+
table definition.
|
32
|
+
|
33
|
+
*Ryuta Kamizono*
|
34
|
+
|
35
|
+
* Fix regression of #1969 with SELECT aliases in HAVING clause.
|
36
|
+
|
37
|
+
*Eugene Kenny*
|
38
|
+
|
39
|
+
|
1
40
|
## Rails 5.0.2 (March 01, 2017) ##
|
2
41
|
|
3
42
|
* Fix `wait_timeout` to configurable for mysql2 adapter.
|
@@ -39,13 +39,7 @@ module ActiveRecord
|
|
39
39
|
reload
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
# Cache the proxy separately before the owner has an id
|
44
|
-
# or else a post-save proxy will still lack the id
|
45
|
-
@null_proxy ||= CollectionProxy.create(klass, self)
|
46
|
-
else
|
47
|
-
@proxy ||= CollectionProxy.create(klass, self)
|
48
|
-
end
|
42
|
+
CollectionProxy.create(klass, self)
|
49
43
|
end
|
50
44
|
|
51
45
|
# Implements the writer method, e.g. foo.items= for Foo.has_many :items
|
@@ -427,37 +421,9 @@ module ActiveRecord
|
|
427
421
|
replace_on_target(record, index, skip_callbacks, &block)
|
428
422
|
end
|
429
423
|
|
430
|
-
def
|
431
|
-
|
432
|
-
|
433
|
-
begin
|
434
|
-
if index
|
435
|
-
record_was = target[index]
|
436
|
-
target[index] = record
|
437
|
-
else
|
438
|
-
target << record
|
439
|
-
end
|
440
|
-
|
441
|
-
yield(record) if block_given?
|
442
|
-
rescue
|
443
|
-
if index
|
444
|
-
target[index] = record_was
|
445
|
-
else
|
446
|
-
target.delete(record)
|
447
|
-
end
|
448
|
-
|
449
|
-
raise
|
450
|
-
end
|
451
|
-
|
452
|
-
callback(:after_add, record) unless skip_callbacks
|
453
|
-
set_inverse_instance(record)
|
454
|
-
|
455
|
-
record
|
456
|
-
end
|
457
|
-
|
458
|
-
def scope(opts = {})
|
459
|
-
scope = super()
|
460
|
-
scope.none! if opts.fetch(:nullify, true) && null_scope?
|
424
|
+
def scope
|
425
|
+
scope = super
|
426
|
+
scope.none! if null_scope?
|
461
427
|
scope
|
462
428
|
end
|
463
429
|
|
@@ -528,15 +494,19 @@ module ActiveRecord
|
|
528
494
|
transaction do
|
529
495
|
add_to_target(build_record(attributes)) do |record|
|
530
496
|
yield(record) if block_given?
|
531
|
-
insert_record(record, true, raise)
|
497
|
+
insert_record(record, true, raise) { @_was_loaded = loaded? }
|
532
498
|
end
|
533
499
|
end
|
534
500
|
end
|
535
501
|
end
|
536
502
|
|
537
503
|
# Do the relevant stuff to insert the given record into the association collection.
|
538
|
-
def insert_record(record, validate = true, raise = false)
|
539
|
-
raise
|
504
|
+
def insert_record(record, validate = true, raise = false, &block)
|
505
|
+
if raise
|
506
|
+
record.save!(validate: validate, &block)
|
507
|
+
else
|
508
|
+
record.save(validate: validate, &block)
|
509
|
+
end
|
540
510
|
end
|
541
511
|
|
542
512
|
def create_scope
|
@@ -590,19 +560,41 @@ module ActiveRecord
|
|
590
560
|
end
|
591
561
|
end
|
592
562
|
|
593
|
-
def concat_records(records,
|
563
|
+
def concat_records(records, raise = false)
|
594
564
|
result = true
|
595
565
|
|
596
566
|
records.each do |record|
|
597
567
|
raise_on_type_mismatch!(record)
|
598
|
-
add_to_target(record) do
|
599
|
-
result &&= insert_record(
|
568
|
+
add_to_target(record) do
|
569
|
+
result &&= insert_record(record, true, raise) { @_was_loaded = loaded? } unless owner.new_record?
|
600
570
|
end
|
601
571
|
end
|
602
572
|
|
603
573
|
result && records
|
604
574
|
end
|
605
575
|
|
576
|
+
def replace_on_target(record, index, skip_callbacks)
|
577
|
+
callback(:before_add, record) unless skip_callbacks
|
578
|
+
|
579
|
+
set_inverse_instance(record)
|
580
|
+
|
581
|
+
@_was_loaded = true
|
582
|
+
|
583
|
+
yield(record) if block_given?
|
584
|
+
|
585
|
+
if index
|
586
|
+
target[index] = record
|
587
|
+
elsif @_was_loaded || !loaded?
|
588
|
+
target << record
|
589
|
+
end
|
590
|
+
|
591
|
+
callback(:after_add, record) unless skip_callbacks
|
592
|
+
|
593
|
+
record
|
594
|
+
ensure
|
595
|
+
@_was_loaded = nil
|
596
|
+
end
|
597
|
+
|
606
598
|
def callback(method, record)
|
607
599
|
callbacks_for(method).each do |callback|
|
608
600
|
callback.call(method, owner, record)
|
@@ -28,12 +28,9 @@ module ActiveRecord
|
|
28
28
|
# is computed directly through SQL and does not trigger by itself the
|
29
29
|
# instantiation of the actual post records.
|
30
30
|
class CollectionProxy < Relation
|
31
|
-
delegate :exists?, :update_all, :arel, to: :scope
|
32
|
-
|
33
31
|
def initialize(klass, association) #:nodoc:
|
34
32
|
@association = association
|
35
33
|
super klass, klass.arel_table, klass.predicate_builder
|
36
|
-
merge! association.scope(nullify: false)
|
37
34
|
end
|
38
35
|
|
39
36
|
def target
|
@@ -902,19 +899,10 @@ module ActiveRecord
|
|
902
899
|
@association
|
903
900
|
end
|
904
901
|
|
905
|
-
# We don't want this object to be put on the scoping stack, because
|
906
|
-
# that could create an infinite loop where we call an @association
|
907
|
-
# method, which gets the current scope, which is this object, which
|
908
|
-
# delegates to @association, and so on.
|
909
|
-
def scoping
|
910
|
-
@association.scope.scoping { yield }
|
911
|
-
end
|
912
|
-
|
913
902
|
# Returns a <tt>Relation</tt> object for the records in this association
|
914
903
|
def scope
|
915
|
-
@association.scope
|
904
|
+
@scope ||= @association.scope
|
916
905
|
end
|
917
|
-
alias spawn scope
|
918
906
|
|
919
907
|
# Equivalent to <tt>Array#==</tt>. Returns +true+ if the two arrays
|
920
908
|
# contain the same number of elements and if each element is equal
|
@@ -1046,6 +1034,7 @@ module ActiveRecord
|
|
1046
1034
|
# person.pets(true) # fetches pets from the database
|
1047
1035
|
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
1048
1036
|
def reload
|
1037
|
+
@scope = nil
|
1049
1038
|
proxy_association.reload
|
1050
1039
|
self
|
1051
1040
|
end
|
@@ -1067,20 +1056,51 @@ module ActiveRecord
|
|
1067
1056
|
# person.pets # fetches pets from the database
|
1068
1057
|
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
1069
1058
|
def reset
|
1059
|
+
@scope = nil
|
1070
1060
|
proxy_association.reset
|
1071
1061
|
proxy_association.reset_scope
|
1072
1062
|
self
|
1073
1063
|
end
|
1074
1064
|
|
1065
|
+
delegate_methods = [
|
1066
|
+
QueryMethods,
|
1067
|
+
SpawnMethods,
|
1068
|
+
].flat_map { |klass|
|
1069
|
+
klass.public_instance_methods(false)
|
1070
|
+
} - self.public_instance_methods(false) + [:scoping]
|
1071
|
+
|
1072
|
+
delegate(*delegate_methods, to: :scope)
|
1073
|
+
|
1074
|
+
module DelegateExtending # :nodoc:
|
1075
|
+
private
|
1076
|
+
def method_missing(method, *args, &block)
|
1077
|
+
extending_values = association_scope.extending_values
|
1078
|
+
if extending_values.any? && (extending_values - self.class.included_modules).any?
|
1079
|
+
self.class.include(*extending_values)
|
1080
|
+
public_send(method, *args, &block)
|
1081
|
+
else
|
1082
|
+
super
|
1083
|
+
end
|
1084
|
+
end
|
1085
|
+
end
|
1086
|
+
|
1075
1087
|
private
|
1076
1088
|
|
1077
1089
|
def null_scope?
|
1078
1090
|
@association.null_scope?
|
1079
1091
|
end
|
1080
1092
|
|
1093
|
+
def association_scope
|
1094
|
+
@association.association_scope
|
1095
|
+
end
|
1096
|
+
|
1081
1097
|
def exec_queries
|
1082
1098
|
load_target
|
1083
1099
|
end
|
1100
|
+
|
1101
|
+
def respond_to_missing?(method, _)
|
1102
|
+
association_scope.respond_to?(method) || super
|
1103
|
+
end
|
1084
1104
|
end
|
1085
1105
|
end
|
1086
1106
|
end
|
@@ -40,13 +40,7 @@ module ActiveRecord
|
|
40
40
|
|
41
41
|
def insert_record(record, validate = true, raise = false)
|
42
42
|
set_owner_attributes(record)
|
43
|
-
|
44
|
-
|
45
|
-
if raise
|
46
|
-
record.save!(:validate => validate)
|
47
|
-
else
|
48
|
-
record.save(:validate => validate)
|
49
|
-
end
|
43
|
+
super
|
50
44
|
end
|
51
45
|
|
52
46
|
def empty?
|
@@ -39,11 +39,7 @@ module ActiveRecord
|
|
39
39
|
ensure_not_nested
|
40
40
|
|
41
41
|
if record.new_record? || record.changed?
|
42
|
-
|
43
|
-
record.save!(validate: validate)
|
44
|
-
else
|
45
|
-
return unless record.save(validate: validate)
|
46
|
-
end
|
42
|
+
return unless super
|
47
43
|
end
|
48
44
|
|
49
45
|
save_through_record(record)
|
@@ -8,17 +8,27 @@ module ActiveRecord
|
|
8
8
|
if collection.loaded?
|
9
9
|
size = collection.size
|
10
10
|
if size > 0
|
11
|
-
timestamp = collection.max_by(×tamp_column).
|
11
|
+
timestamp = collection.max_by(×tamp_column)._read_attribute(timestamp_column)
|
12
12
|
end
|
13
13
|
else
|
14
14
|
column_type = type_for_attribute(timestamp_column.to_s)
|
15
15
|
column = "#{connection.quote_table_name(collection.table_name)}.#{connection.quote_column_name(timestamp_column)}"
|
16
|
+
select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
|
16
17
|
|
17
|
-
|
18
|
-
.
|
19
|
-
.
|
20
|
-
|
21
|
-
|
18
|
+
if collection.limit_value || collection.offset_value
|
19
|
+
query = collection.spawn
|
20
|
+
query.select_values = [column]
|
21
|
+
subquery_alias = "subquery_for_cache_key"
|
22
|
+
subquery_column = "#{subquery_alias}.#{timestamp_column}"
|
23
|
+
subquery = query.arel.as(subquery_alias)
|
24
|
+
arel = Arel::SelectManager.new(query.engine).project(select_values % subquery_column).from(subquery)
|
25
|
+
else
|
26
|
+
query = collection.unscope(:order)
|
27
|
+
query.select_values = [select_values % column]
|
28
|
+
arel = query.arel
|
29
|
+
end
|
30
|
+
|
31
|
+
result = connection.select_one(arel, nil, query.bound_attributes)
|
22
32
|
|
23
33
|
if result.blank?
|
24
34
|
size = 0
|
@@ -155,6 +155,14 @@ module ActiveRecord
|
|
155
155
|
binds.map(&:value_for_database)
|
156
156
|
end
|
157
157
|
|
158
|
+
def type_casted_binds(binds) # :nodoc:
|
159
|
+
if binds.first.is_a?(Array)
|
160
|
+
binds.map { |column, value| type_cast(value, column) }
|
161
|
+
else
|
162
|
+
binds.map { |attr| type_cast(attr.value_for_database) }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
158
166
|
private
|
159
167
|
|
160
168
|
def types_which_need_no_typecasting
|
@@ -107,16 +107,12 @@ module ActiveRecord
|
|
107
107
|
|
108
108
|
private
|
109
109
|
|
110
|
-
def as_options(value
|
111
|
-
|
112
|
-
value
|
113
|
-
else
|
114
|
-
default
|
115
|
-
end
|
110
|
+
def as_options(value)
|
111
|
+
value.is_a?(Hash) ? value : {}
|
116
112
|
end
|
117
113
|
|
118
114
|
def polymorphic_options
|
119
|
-
as_options(polymorphic
|
115
|
+
as_options(polymorphic)
|
120
116
|
end
|
121
117
|
|
122
118
|
def index_options
|
@@ -1022,9 +1022,8 @@ module ActiveRecord
|
|
1022
1022
|
sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
|
1023
1023
|
|
1024
1024
|
migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i)
|
1025
|
-
|
1026
|
-
|
1027
|
-
filename.split('/').last.split('_').first.to_i
|
1025
|
+
versions = ActiveRecord::Migrator.migration_files(migrations_paths).map do |file|
|
1026
|
+
ActiveRecord::Migrator.parse_migration_filename(file).first.to_i
|
1028
1027
|
end
|
1029
1028
|
|
1030
1029
|
unless migrated.include?(version)
|
@@ -425,7 +425,7 @@ module ActiveRecord
|
|
425
425
|
|
426
426
|
# Provides access to the underlying database driver for this adapter. For
|
427
427
|
# example, this method returns a Mysql2::Client object in case of Mysql2Adapter,
|
428
|
-
# and a
|
428
|
+
# and a PG::Connection object in case of PostgreSQLAdapter.
|
429
429
|
#
|
430
430
|
# This is useful for when you need to call a proprietary method such as
|
431
431
|
# PostgreSQL's lo_* methods.
|
@@ -579,14 +579,15 @@ module ActiveRecord
|
|
579
579
|
exception
|
580
580
|
end
|
581
581
|
|
582
|
-
def log(sql, name = "SQL", binds = [], statement_name = nil)
|
582
|
+
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil)
|
583
583
|
@instrumenter.instrument(
|
584
584
|
"sql.active_record",
|
585
|
-
:sql
|
586
|
-
:name
|
587
|
-
:
|
588
|
-
:
|
589
|
-
:
|
585
|
+
sql: sql,
|
586
|
+
name: name,
|
587
|
+
binds: binds,
|
588
|
+
type_casted_binds: type_casted_binds,
|
589
|
+
statement_name: statement_name,
|
590
|
+
connection_id: object_id) { yield }
|
590
591
|
rescue => e
|
591
592
|
raise translate_exception_class(e, sql)
|
592
593
|
end
|
@@ -324,7 +324,7 @@ module ActiveRecord
|
|
324
324
|
|
325
325
|
def data_sources
|
326
326
|
sql = "SELECT table_name FROM information_schema.tables "
|
327
|
-
sql << "WHERE table_schema =
|
327
|
+
sql << "WHERE table_schema = DATABASE()"
|
328
328
|
|
329
329
|
select_values(sql, 'SCHEMA')
|
330
330
|
end
|
@@ -350,7 +350,7 @@ module ActiveRecord
|
|
350
350
|
schema, name = extract_schema_qualified_name(table_name)
|
351
351
|
|
352
352
|
sql = "SELECT table_name FROM information_schema.tables "
|
353
|
-
sql << "WHERE table_schema = #{
|
353
|
+
sql << "WHERE table_schema = #{schema} AND table_name = #{name}"
|
354
354
|
|
355
355
|
select_values(sql, 'SCHEMA').any?
|
356
356
|
end
|
@@ -365,7 +365,7 @@ module ActiveRecord
|
|
365
365
|
schema, name = extract_schema_qualified_name(view_name)
|
366
366
|
|
367
367
|
sql = "SELECT table_name FROM information_schema.tables WHERE table_type = 'VIEW'"
|
368
|
-
sql << " AND table_schema = #{
|
368
|
+
sql << " AND table_schema = #{schema} AND table_name = #{name}"
|
369
369
|
|
370
370
|
select_values(sql, 'SCHEMA').any?
|
371
371
|
end
|
@@ -414,8 +414,8 @@ module ActiveRecord
|
|
414
414
|
select_value(<<-SQL.strip_heredoc, 'SCHEMA')
|
415
415
|
SELECT table_comment
|
416
416
|
FROM information_schema.tables
|
417
|
-
WHERE table_schema = #{
|
418
|
-
AND table_name = #{
|
417
|
+
WHERE table_schema = #{schema}
|
418
|
+
AND table_name = #{name}
|
419
419
|
SQL
|
420
420
|
end
|
421
421
|
|
@@ -528,9 +528,9 @@ module ActiveRecord
|
|
528
528
|
JOIN information_schema.referential_constraints rc
|
529
529
|
USING (constraint_schema, constraint_name)
|
530
530
|
WHERE fk.referenced_column_name IS NOT NULL
|
531
|
-
AND fk.table_schema = #{
|
532
|
-
AND fk.table_name = #{
|
533
|
-
AND rc.table_name = #{
|
531
|
+
AND fk.table_schema = #{schema}
|
532
|
+
AND fk.table_name = #{name}
|
533
|
+
AND rc.table_name = #{name}
|
534
534
|
SQL
|
535
535
|
|
536
536
|
fk_info.map do |row|
|
@@ -607,8 +607,8 @@ module ActiveRecord
|
|
607
607
|
SELECT column_name
|
608
608
|
FROM information_schema.key_column_usage
|
609
609
|
WHERE constraint_name = 'PRIMARY'
|
610
|
-
AND table_schema = #{
|
611
|
-
AND table_name = #{
|
610
|
+
AND table_schema = #{schema}
|
611
|
+
AND table_name = #{name}
|
612
612
|
ORDER BY ordinal_position
|
613
613
|
SQL
|
614
614
|
end
|
@@ -904,8 +904,8 @@ module ActiveRecord
|
|
904
904
|
end
|
905
905
|
|
906
906
|
def extract_schema_qualified_name(string) # :nodoc:
|
907
|
-
schema, name = string.to_s.scan(/[^`.\s]+|`[^`]*`/)
|
908
|
-
schema, name =
|
907
|
+
schema, name = string.to_s.scan(/[^`.\s]+|`[^`]*`/).map { |s| quote(s) }
|
908
|
+
schema, name = "DATABASE()", schema unless name
|
909
909
|
[schema, name]
|
910
910
|
end
|
911
911
|
|
@@ -73,9 +73,9 @@ module ActiveRecord
|
|
73
73
|
# made since we established the connection
|
74
74
|
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
75
75
|
|
76
|
-
type_casted_binds = binds
|
76
|
+
type_casted_binds = type_casted_binds(binds)
|
77
77
|
|
78
|
-
log(sql, name, binds) do
|
78
|
+
log(sql, name, binds, type_casted_binds) do
|
79
79
|
if cache_stmt
|
80
80
|
cache = @statements[sql] ||= {
|
81
81
|
stmt: @connection.prepare(sql)
|
@@ -33,7 +33,7 @@ module ActiveRecord
|
|
33
33
|
|
34
34
|
# Quotes schema names for use in SQL queries.
|
35
35
|
def quote_schema_name(name)
|
36
|
-
|
36
|
+
PG::Connection.quote_ident(name)
|
37
37
|
end
|
38
38
|
|
39
39
|
def quote_table_name_for_assignment(table, attr)
|
@@ -42,7 +42,7 @@ module ActiveRecord
|
|
42
42
|
|
43
43
|
# Quotes column names for use in SQL queries.
|
44
44
|
def quote_column_name(name) # :nodoc:
|
45
|
-
@quoted_column_names[name] ||=
|
45
|
+
@quoted_column_names[name] ||= PG::Connection.quote_ident(super)
|
46
46
|
end
|
47
47
|
|
48
48
|
# Quote date/time values for use in SQL input.
|
@@ -103,7 +103,7 @@ module ActiveRecord
|
|
103
103
|
case value
|
104
104
|
when Type::Binary::Data
|
105
105
|
# Return a bind param hash with format as binary.
|
106
|
-
# See
|
106
|
+
# See https://deveiate.org/code/pg/PG/Connection.html#method-i-exec_prepared-doc
|
107
107
|
# for more information
|
108
108
|
{ value: value.to_s, format: 1 }
|
109
109
|
when OID::Xml::Data, OID::Bit::Data
|
@@ -19,9 +19,9 @@ module ActiveRecord
|
|
19
19
|
|
20
20
|
def quoted
|
21
21
|
if schema
|
22
|
-
|
22
|
+
PG::Connection.quote_ident(schema) << SEPARATOR << PG::Connection.quote_ident(identifier)
|
23
23
|
else
|
24
|
-
|
24
|
+
PG::Connection.quote_ident(identifier)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -28,11 +28,11 @@ module ActiveRecord
|
|
28
28
|
conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
|
29
29
|
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
|
30
30
|
|
31
|
-
# Forward only valid config params to
|
32
|
-
valid_conn_param_keys =
|
31
|
+
# Forward only valid config params to PG::Connection.connect.
|
32
|
+
valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
|
33
33
|
conn_params.slice!(*valid_conn_param_keys)
|
34
34
|
|
35
|
-
# The postgres drivers don't allow the creation of an unconnected
|
35
|
+
# The postgres drivers don't allow the creation of an unconnected PG::Connection object,
|
36
36
|
# so just pass a nil connection object for the time being.
|
37
37
|
ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, conn_params, config)
|
38
38
|
end
|
@@ -198,8 +198,8 @@ module ActiveRecord
|
|
198
198
|
end
|
199
199
|
|
200
200
|
def connection_active?
|
201
|
-
@connection.status ==
|
202
|
-
rescue
|
201
|
+
@connection.status == PG::CONNECTION_OK
|
202
|
+
rescue PG::Error
|
203
203
|
false
|
204
204
|
end
|
205
205
|
end
|
@@ -244,7 +244,7 @@ module ActiveRecord
|
|
244
244
|
def active?
|
245
245
|
@connection.query 'SELECT 1'
|
246
246
|
true
|
247
|
-
rescue
|
247
|
+
rescue PG::Error
|
248
248
|
false
|
249
249
|
end
|
250
250
|
|
@@ -410,7 +410,7 @@ module ActiveRecord
|
|
410
410
|
def translate_exception(exception, message)
|
411
411
|
return exception unless exception.respond_to?(:result)
|
412
412
|
|
413
|
-
case exception.result.try(:error_field,
|
413
|
+
case exception.result.try(:error_field, PG::PG_DIAG_SQLSTATE)
|
414
414
|
when UNIQUE_VIOLATION
|
415
415
|
RecordNotUnique.new(message)
|
416
416
|
when FOREIGN_KEY_VIOLATION
|
@@ -594,15 +594,15 @@ module ActiveRecord
|
|
594
594
|
end
|
595
595
|
|
596
596
|
def exec_no_cache(sql, name, binds)
|
597
|
-
type_casted_binds = binds
|
598
|
-
log(sql, name, binds) { @connection.async_exec(sql, type_casted_binds) }
|
597
|
+
type_casted_binds = type_casted_binds(binds)
|
598
|
+
log(sql, name, binds, type_casted_binds) { @connection.async_exec(sql, type_casted_binds) }
|
599
599
|
end
|
600
600
|
|
601
601
|
def exec_cache(sql, name, binds)
|
602
602
|
stmt_key = prepare_statement(sql)
|
603
|
-
type_casted_binds = binds
|
603
|
+
type_casted_binds = type_casted_binds(binds)
|
604
604
|
|
605
|
-
log(sql, name, binds, stmt_key) do
|
605
|
+
log(sql, name, binds, type_casted_binds, stmt_key) do
|
606
606
|
@connection.exec_prepared(stmt_key, type_casted_binds)
|
607
607
|
end
|
608
608
|
rescue ActiveRecord::StatementInvalid => e
|
@@ -631,7 +631,7 @@ module ActiveRecord
|
|
631
631
|
CACHED_PLAN_HEURISTIC = 'cached plan must not change result type'.freeze
|
632
632
|
def is_cached_plan_failure?(e)
|
633
633
|
pgerror = e.cause
|
634
|
-
code = pgerror.result.result_error_field(
|
634
|
+
code = pgerror.result.result_error_field(PG::PG_DIAG_SQLSTATE)
|
635
635
|
code == FEATURE_NOT_SUPPORTED && pgerror.message.include?(CACHED_PLAN_HEURISTIC)
|
636
636
|
rescue
|
637
637
|
false
|
@@ -668,7 +668,7 @@ module ActiveRecord
|
|
668
668
|
# Connects to a PostgreSQL server and sets up the adapter depending on the
|
669
669
|
# connected server's characteristics.
|
670
670
|
def connect
|
671
|
-
@connection =
|
671
|
+
@connection = PG.connect(@connection_parameters)
|
672
672
|
configure_connection
|
673
673
|
rescue ::PG::Error => error
|
674
674
|
if error.message.include?("does not exist")
|
@@ -188,9 +188,9 @@ module ActiveRecord
|
|
188
188
|
end
|
189
189
|
|
190
190
|
def exec_query(sql, name = nil, binds = [], prepare: false)
|
191
|
-
type_casted_binds = binds
|
191
|
+
type_casted_binds = type_casted_binds(binds)
|
192
192
|
|
193
|
-
log(sql, name, binds) do
|
193
|
+
log(sql, name, binds, type_casted_binds) do
|
194
194
|
# Don't cache statements if they are not prepared
|
195
195
|
unless prepare
|
196
196
|
stmt = @connection.prepare(sql)
|
@@ -203,7 +203,6 @@ module ActiveRecord
|
|
203
203
|
ensure
|
204
204
|
stmt.close
|
205
205
|
end
|
206
|
-
stmt = records
|
207
206
|
else
|
208
207
|
cache = @statements[sql] ||= {
|
209
208
|
:stmt => @connection.prepare(sql)
|
@@ -212,9 +211,10 @@ module ActiveRecord
|
|
212
211
|
cols = cache[:cols] ||= stmt.columns
|
213
212
|
stmt.reset!
|
214
213
|
stmt.bind_params(type_casted_binds)
|
214
|
+
records = stmt.to_a
|
215
215
|
end
|
216
216
|
|
217
|
-
ActiveRecord::Result.new(cols,
|
217
|
+
ActiveRecord::Result.new(cols, records)
|
218
218
|
end
|
219
219
|
end
|
220
220
|
|
@@ -16,15 +16,14 @@ module ActiveRecord
|
|
16
16
|
# Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
|
17
17
|
# Returns a formatted string ready to be logged.
|
18
18
|
def exec_explain(queries) # :nodoc:
|
19
|
-
str = queries.map do |sql,
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end.join("\n")
|
19
|
+
str = queries.map do |sql, binds|
|
20
|
+
msg = "EXPLAIN for: #{sql}"
|
21
|
+
unless binds.empty?
|
22
|
+
msg << " "
|
23
|
+
msg << binds.map { |attr| render_bind(attr) }.inspect
|
24
|
+
end
|
25
|
+
msg << "\n"
|
26
|
+
msg << connection.explain(sql, binds)
|
28
27
|
end.join("\n")
|
29
28
|
|
30
29
|
# Overriding inspect to be more human readable, especially in the console.
|
@@ -34,5 +33,17 @@ module ActiveRecord
|
|
34
33
|
|
35
34
|
str
|
36
35
|
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def render_bind(attr)
|
40
|
+
value = if attr.type.binary? && attr.value
|
41
|
+
"<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
|
42
|
+
else
|
43
|
+
connection.type_cast(attr.value_for_database)
|
44
|
+
end
|
45
|
+
|
46
|
+
[attr.name, value]
|
47
|
+
end
|
37
48
|
end
|
38
49
|
end
|
@@ -20,20 +20,6 @@ module ActiveRecord
|
|
20
20
|
@odd = false
|
21
21
|
end
|
22
22
|
|
23
|
-
def render_bind(attribute)
|
24
|
-
value = if attribute.type.binary? && attribute.value
|
25
|
-
if attribute.value.is_a?(Hash)
|
26
|
-
"<#{attribute.value_for_database.to_s.bytesize} bytes of binary data>"
|
27
|
-
else
|
28
|
-
"<#{attribute.value.bytesize} bytes of binary data>"
|
29
|
-
end
|
30
|
-
else
|
31
|
-
attribute.value_for_database
|
32
|
-
end
|
33
|
-
|
34
|
-
[attribute.name, value]
|
35
|
-
end
|
36
|
-
|
37
23
|
def sql(event)
|
38
24
|
self.class.runtime += event.duration
|
39
25
|
return unless logger.debug?
|
@@ -47,7 +33,10 @@ module ActiveRecord
|
|
47
33
|
binds = nil
|
48
34
|
|
49
35
|
unless (payload[:binds] || []).empty?
|
50
|
-
|
36
|
+
casted_params = type_casted_binds(payload[:binds], payload[:type_casted_binds])
|
37
|
+
binds = " " + payload[:binds].zip(casted_params).map { |attr, value|
|
38
|
+
render_bind(attr, value)
|
39
|
+
}.inspect
|
51
40
|
end
|
52
41
|
|
53
42
|
name = colorize_payload_name(name, payload[:name])
|
@@ -58,6 +47,20 @@ module ActiveRecord
|
|
58
47
|
|
59
48
|
private
|
60
49
|
|
50
|
+
def type_casted_binds(binds, casted_binds)
|
51
|
+
casted_binds || ActiveRecord::Base.connection.type_casted_binds(binds)
|
52
|
+
end
|
53
|
+
|
54
|
+
def render_bind(attr, value)
|
55
|
+
if attr.is_a?(Array)
|
56
|
+
attr = attr.first
|
57
|
+
elsif attr.type.binary? && attr.value
|
58
|
+
value = "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
|
59
|
+
end
|
60
|
+
|
61
|
+
[attr && attr.name, value]
|
62
|
+
end
|
63
|
+
|
61
64
|
def colorize_payload_name(name, payload_name)
|
62
65
|
if payload_name.blank? || payload_name == "SQL" # SQL vs Model Load/Exists
|
63
66
|
color(name, MAGENTA, true)
|
@@ -1057,10 +1057,6 @@ module ActiveRecord
|
|
1057
1057
|
Array(@migrations_paths)
|
1058
1058
|
end
|
1059
1059
|
|
1060
|
-
def match_to_migration_filename?(filename) # :nodoc:
|
1061
|
-
File.basename(filename) =~ Migration::MigrationFilenameRegexp
|
1062
|
-
end
|
1063
|
-
|
1064
1060
|
def parse_migration_filename(filename) # :nodoc:
|
1065
1061
|
File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
|
1066
1062
|
end
|
@@ -1068,9 +1064,7 @@ module ActiveRecord
|
|
1068
1064
|
def migrations(paths)
|
1069
1065
|
paths = Array(paths)
|
1070
1066
|
|
1071
|
-
|
1072
|
-
|
1073
|
-
migrations = files.map do |file|
|
1067
|
+
migrations = migration_files(paths).map do |file|
|
1074
1068
|
version, name, scope = parse_migration_filename(file)
|
1075
1069
|
raise IllegalMigrationNameError.new(file) unless version
|
1076
1070
|
version = version.to_i
|
@@ -1082,6 +1076,30 @@ module ActiveRecord
|
|
1082
1076
|
migrations.sort_by(&:version)
|
1083
1077
|
end
|
1084
1078
|
|
1079
|
+
def migrations_status(paths)
|
1080
|
+
paths = Array(paths)
|
1081
|
+
|
1082
|
+
db_list = ActiveRecord::SchemaMigration.normalized_versions
|
1083
|
+
|
1084
|
+
file_list = migration_files(paths).map do |file|
|
1085
|
+
version, name, scope = parse_migration_filename(file)
|
1086
|
+
raise IllegalMigrationNameError.new(file) unless version
|
1087
|
+
version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
|
1088
|
+
status = db_list.delete(version) ? "up" : "down"
|
1089
|
+
[status, version, (name + scope).humanize]
|
1090
|
+
end.compact
|
1091
|
+
|
1092
|
+
db_list.map! do |version|
|
1093
|
+
["up", version, "********** NO FILE **********"]
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
(db_list + file_list).sort_by { |_, version, _| version }
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
def migration_files(paths)
|
1100
|
+
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
1101
|
+
end
|
1102
|
+
|
1085
1103
|
private
|
1086
1104
|
|
1087
1105
|
def move(direction, migrations_paths, steps)
|
@@ -100,6 +100,10 @@ module ActiveRecord
|
|
100
100
|
!(@new_record || @destroyed)
|
101
101
|
end
|
102
102
|
|
103
|
+
##
|
104
|
+
# :call-seq:
|
105
|
+
# save(*args)
|
106
|
+
#
|
103
107
|
# Saves the model.
|
104
108
|
#
|
105
109
|
# If the model is new, a record gets created in the database, otherwise
|
@@ -121,12 +125,16 @@ module ActiveRecord
|
|
121
125
|
#
|
122
126
|
# Attributes marked as readonly are silently ignored if the record is
|
123
127
|
# being updated.
|
124
|
-
def save(*args)
|
125
|
-
create_or_update(*args)
|
128
|
+
def save(*args, &block)
|
129
|
+
create_or_update(*args, &block)
|
126
130
|
rescue ActiveRecord::RecordInvalid
|
127
131
|
false
|
128
132
|
end
|
129
133
|
|
134
|
+
##
|
135
|
+
# :call-seq:
|
136
|
+
# save!(*args)
|
137
|
+
#
|
130
138
|
# Saves the model.
|
131
139
|
#
|
132
140
|
# If the model is new, a record gets created in the database, otherwise
|
@@ -148,8 +156,8 @@ module ActiveRecord
|
|
148
156
|
#
|
149
157
|
# Attributes marked as readonly are silently ignored if the record is
|
150
158
|
# being updated.
|
151
|
-
def save!(*args)
|
152
|
-
create_or_update(*args) || raise(RecordNotSaved.new("Failed to save the record", self))
|
159
|
+
def save!(*args, &block)
|
160
|
+
create_or_update(*args, &block) || raise(RecordNotSaved.new("Failed to save the record", self))
|
153
161
|
end
|
154
162
|
|
155
163
|
# Deletes the record in the database and freezes this instance to
|
@@ -535,9 +543,9 @@ module ActiveRecord
|
|
535
543
|
self.class.unscoped.where(self.class.primary_key => id)
|
536
544
|
end
|
537
545
|
|
538
|
-
def create_or_update(*args)
|
546
|
+
def create_or_update(*args, &block)
|
539
547
|
raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
|
540
|
-
result = new_record? ? _create_record : _update_record(*args)
|
548
|
+
result = new_record? ? _create_record(&block) : _update_record(*args, &block)
|
541
549
|
result != false
|
542
550
|
end
|
543
551
|
|
@@ -546,10 +554,14 @@ module ActiveRecord
|
|
546
554
|
def _update_record(attribute_names = self.attribute_names)
|
547
555
|
attributes_values = arel_attributes_with_values_for_update(attribute_names)
|
548
556
|
if attributes_values.empty?
|
549
|
-
0
|
557
|
+
rows_affected = 0
|
550
558
|
else
|
551
|
-
self.class.unscoped._update_record attributes_values, id, id_was
|
559
|
+
rows_affected = self.class.unscoped._update_record attributes_values, id, id_was
|
552
560
|
end
|
561
|
+
|
562
|
+
yield(self) if block_given?
|
563
|
+
|
564
|
+
rows_affected
|
553
565
|
end
|
554
566
|
|
555
567
|
# Creates a record with values matching those of the instance attributes
|
@@ -561,6 +573,9 @@ module ActiveRecord
|
|
561
573
|
self.id ||= new_id if self.class.primary_key
|
562
574
|
|
563
575
|
@new_record = false
|
576
|
+
|
577
|
+
yield(self) if block_given?
|
578
|
+
|
564
579
|
id
|
565
580
|
end
|
566
581
|
|
@@ -77,6 +77,8 @@ db_namespace = namespace :db do
|
|
77
77
|
namespace :migrate do
|
78
78
|
# desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
|
79
79
|
task :redo => [:environment, :load_config] do
|
80
|
+
raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
|
81
|
+
|
80
82
|
if ENV['VERSION']
|
81
83
|
db_namespace['migrate:down'].invoke
|
82
84
|
db_namespace['migrate:up'].invoke
|
@@ -91,16 +93,17 @@ db_namespace = namespace :db do
|
|
91
93
|
|
92
94
|
# desc 'Runs the "up" for a given migration VERSION.'
|
93
95
|
task :up => [:environment, :load_config] do
|
96
|
+
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
97
|
+
|
94
98
|
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
95
|
-
raise 'VERSION is required' unless version
|
96
99
|
ActiveRecord::Migrator.run(:up, ActiveRecord::Tasks::DatabaseTasks.migrations_paths, version)
|
97
100
|
db_namespace['_dump'].invoke
|
98
101
|
end
|
99
102
|
|
100
103
|
# desc 'Runs the "down" for a given migration VERSION.'
|
101
104
|
task :down => [:environment, :load_config] do
|
105
|
+
raise "VERSION is required - To go down one migration, use db:rollback" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
102
106
|
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
103
|
-
raise 'VERSION is required - To go down one migration, run db:rollback' unless version
|
104
107
|
ActiveRecord::Migrator.run(:down, ActiveRecord::Tasks::DatabaseTasks.migrations_paths, version)
|
105
108
|
db_namespace['_dump'].invoke
|
106
109
|
end
|
@@ -110,28 +113,13 @@ db_namespace = namespace :db do
|
|
110
113
|
unless ActiveRecord::SchemaMigration.table_exists?
|
111
114
|
abort 'Schema migrations table does not exist yet.'
|
112
115
|
end
|
113
|
-
db_list = ActiveRecord::SchemaMigration.normalized_versions
|
114
|
-
|
115
|
-
file_list =
|
116
|
-
ActiveRecord::Tasks::DatabaseTasks.migrations_paths.flat_map do |path|
|
117
|
-
Dir.foreach(path).map do |file|
|
118
|
-
next unless ActiveRecord::Migrator.match_to_migration_filename?(file)
|
119
|
-
|
120
|
-
version, name, scope = ActiveRecord::Migrator.parse_migration_filename(file)
|
121
|
-
version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
|
122
|
-
status = db_list.delete(version) ? 'up' : 'down'
|
123
|
-
[status, version, (name + scope).humanize]
|
124
|
-
end.compact
|
125
|
-
end
|
126
116
|
|
127
|
-
db_list.map! do |version|
|
128
|
-
['up', version, '********** NO FILE **********']
|
129
|
-
end
|
130
117
|
# output
|
131
118
|
puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
|
132
119
|
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
133
120
|
puts "-" * 50
|
134
|
-
|
121
|
+
paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
|
122
|
+
ActiveRecord::Migrator.migrations_status(paths).each do |status, version, name|
|
135
123
|
puts "#{status.center(8)} #{version.ljust(14)} #{name}"
|
136
124
|
end
|
137
125
|
puts
|
@@ -282,7 +282,7 @@ module ActiveRecord
|
|
282
282
|
operation,
|
283
283
|
distinct).as(aggregate_alias)
|
284
284
|
]
|
285
|
-
select_values += select_values unless having_clause.empty?
|
285
|
+
select_values += self.select_values unless having_clause.empty?
|
286
286
|
|
287
287
|
select_values.concat group_columns.map { |aliaz, field|
|
288
288
|
if field.respond_to?(:as)
|
@@ -24,6 +24,8 @@ module ActiveRecord
|
|
24
24
|
|
25
25
|
def inherited(child_class)
|
26
26
|
child_class.initialize_relation_delegate_cache
|
27
|
+
delegate = child_class.relation_delegate_class(ActiveRecord::Associations::CollectionProxy)
|
28
|
+
delegate.include ActiveRecord::Associations::CollectionProxy::DelegateExtending
|
27
29
|
super
|
28
30
|
end
|
29
31
|
end
|
@@ -154,6 +154,8 @@ module ActiveRecord
|
|
154
154
|
end
|
155
155
|
|
156
156
|
def migrate
|
157
|
+
raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
|
158
|
+
|
157
159
|
verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
158
160
|
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
159
161
|
scope = ENV['SCOPE']
|
@@ -124,7 +124,7 @@ module ActiveRecord
|
|
124
124
|
# # statement will cause a PostgreSQL error, even though the unique
|
125
125
|
# # constraint is no longer violated:
|
126
126
|
# Number.create(i: 1)
|
127
|
-
# # => "
|
127
|
+
# # => "PG::Error: ERROR: current transaction is aborted, commands
|
128
128
|
# # ignored until end of transaction block"
|
129
129
|
# end
|
130
130
|
#
|
@@ -20,6 +20,14 @@ module ActiveRecord
|
|
20
20
|
key_type = options[:primary_key_type]
|
21
21
|
", id: :#{key_type}" if key_type
|
22
22
|
end
|
23
|
+
|
24
|
+
def db_migrate_path
|
25
|
+
if defined?(Rails.application) && Rails.application
|
26
|
+
Rails.application.config.paths["db/migrate"].to_ary.first
|
27
|
+
else
|
28
|
+
"db/migrate"
|
29
|
+
end
|
30
|
+
end
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|
@@ -68,14 +68,6 @@ module ActiveRecord
|
|
68
68
|
def normalize_table_name(_table_name)
|
69
69
|
pluralize_table_names? ? _table_name.pluralize : _table_name.singularize
|
70
70
|
end
|
71
|
-
|
72
|
-
def db_migrate_path
|
73
|
-
if defined?(Rails) && Rails.application
|
74
|
-
Rails.application.config.paths["db/migrate"].to_ary.first
|
75
|
-
else
|
76
|
-
"db/migrate"
|
77
|
-
end
|
78
|
-
end
|
79
71
|
end
|
80
72
|
end
|
81
73
|
end
|
@@ -64,14 +64,6 @@ module ActiveRecord
|
|
64
64
|
'app/models/application_record.rb'
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
68
|
-
def db_migrate_path
|
69
|
-
if defined?(Rails) && Rails.application
|
70
|
-
Rails.application.config.paths["db/migrate"].to_ary.first
|
71
|
-
else
|
72
|
-
"db/migrate"
|
73
|
-
end
|
74
|
-
end
|
75
67
|
end
|
76
68
|
end
|
77
69
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.0.
|
19
|
+
version: 5.0.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.0.
|
26
|
+
version: 5.0.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 5.0.
|
33
|
+
version: 5.0.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 5.0.
|
40
|
+
version: 5.0.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: arel
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -333,3 +333,4 @@ signing_key:
|
|
333
333
|
specification_version: 4
|
334
334
|
summary: Object-relational mapper framework (part of Rails).
|
335
335
|
test_files: []
|
336
|
+
has_rdoc:
|