activerecord 4.2.0 → 4.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +657 -1
- data/lib/active_record.rb +3 -0
- data/lib/active_record/aggregations.rb +6 -3
- data/lib/active_record/association_relation.rb +13 -0
- data/lib/active_record/associations.rb +5 -4
- data/lib/active_record/associations/association.rb +15 -3
- data/lib/active_record/associations/association_scope.rb +1 -0
- data/lib/active_record/associations/belongs_to_association.rb +13 -5
- data/lib/active_record/associations/builder/association.rb +1 -1
- data/lib/active_record/associations/builder/collection_association.rb +5 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +8 -4
- data/lib/active_record/associations/collection_association.rb +35 -15
- data/lib/active_record/associations/collection_proxy.rb +15 -9
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +30 -15
- data/lib/active_record/associations/has_many_through_association.rb +11 -2
- data/lib/active_record/associations/has_one_association.rb +1 -0
- data/lib/active_record/associations/join_dependency.rb +8 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +7 -1
- data/lib/active_record/associations/preloader.rb +4 -4
- data/lib/active_record/associations/preloader/association.rb +5 -1
- data/lib/active_record/associations/singular_association.rb +2 -8
- data/lib/active_record/associations/through_association.rb +11 -6
- data/lib/active_record/attribute.rb +15 -1
- data/lib/active_record/attribute_assignment.rb +2 -2
- data/lib/active_record/attribute_methods.rb +4 -8
- data/lib/active_record/attribute_methods/before_type_cast.rb +5 -0
- data/lib/active_record/attribute_methods/dirty.rb +14 -4
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +5 -1
- data/lib/active_record/attribute_methods/write.rb +1 -1
- data/lib/active_record/attribute_set.rb +4 -0
- data/lib/active_record/attribute_set/builder.rb +32 -12
- data/lib/active_record/attributes.rb +8 -0
- data/lib/active_record/autosave_association.rb +24 -9
- data/lib/active_record/base.rb +4 -5
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +12 -6
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +23 -3
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +26 -16
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +87 -24
- data/lib/active_record/connection_adapters/abstract/transaction.rb +2 -6
- data/lib/active_record/connection_adapters/abstract_adapter.rb +25 -7
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +73 -10
- data/lib/active_record/connection_adapters/column.rb +2 -2
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +7 -21
- data/lib/active_record/connection_adapters/mysql_adapter.rb +10 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +17 -5
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +21 -13
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +12 -12
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +12 -28
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +28 -15
- data/lib/active_record/counter_cache.rb +1 -1
- data/lib/active_record/enum.rb +2 -3
- data/lib/active_record/errors.rb +6 -5
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixtures.rb +9 -7
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/legacy_yaml_adapter.rb +30 -0
- data/lib/active_record/locking/optimistic.rb +16 -14
- data/lib/active_record/migration.rb +38 -10
- data/lib/active_record/model_schema.rb +4 -2
- data/lib/active_record/nested_attributes.rb +13 -3
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +7 -4
- data/lib/active_record/railtie.rb +5 -3
- data/lib/active_record/railties/databases.rake +17 -24
- data/lib/active_record/reflection.rb +40 -28
- data/lib/active_record/relation.rb +3 -2
- data/lib/active_record/relation/calculations.rb +10 -3
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +4 -16
- data/lib/active_record/relation/merger.rb +24 -1
- data/lib/active_record/relation/predicate_builder.rb +32 -3
- data/lib/active_record/relation/predicate_builder/array_handler.rb +3 -2
- data/lib/active_record/relation/query_methods.rb +29 -27
- data/lib/active_record/relation/spawn_methods.rb +7 -3
- data/lib/active_record/schema_dumper.rb +1 -1
- data/lib/active_record/schema_migration.rb +1 -4
- data/lib/active_record/scoping/default.rb +1 -0
- data/lib/active_record/tasks/database_tasks.rb +5 -2
- data/lib/active_record/tasks/mysql_database_tasks.rb +30 -16
- data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -8
- data/lib/active_record/transactions.rb +21 -11
- data/lib/active_record/type/boolean.rb +1 -0
- data/lib/active_record/type/date.rb +4 -0
- data/lib/active_record/type/date_time.rb +14 -3
- data/lib/active_record/type/decimal.rb +27 -3
- data/lib/active_record/type/hash_lookup_type_map.rb +8 -2
- data/lib/active_record/type/integer.rb +9 -5
- data/lib/active_record/type/numeric.rb +1 -1
- data/lib/active_record/type/serialized.rb +7 -1
- data/lib/active_record/type/string.rb +4 -0
- data/lib/active_record/type/value.rb +9 -0
- data/lib/active_record/validations/uniqueness.rb +16 -6
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -3
- data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -6
- metadata +9 -7
@@ -5,6 +5,15 @@ module ActiveRecord
|
|
5
5
|
class DateTime < Type::DateTime # :nodoc:
|
6
6
|
include Infinity
|
7
7
|
|
8
|
+
def type_cast_for_database(value)
|
9
|
+
if has_precision? && value.acts_like?(:time) && value.year <= 0
|
10
|
+
bce_year = format("%04d", -value.year + 1)
|
11
|
+
super.sub(/^-?\d+/, bce_year) + " BC"
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
8
17
|
def cast_value(value)
|
9
18
|
if value.is_a?(::String)
|
10
19
|
case value
|
@@ -15,11 +15,11 @@ module ActiveRecord
|
|
15
15
|
def run(records)
|
16
16
|
nodes = records.reject { |row| @store.key? row['oid'].to_i }
|
17
17
|
mapped, nodes = nodes.partition { |row| @store.key? row['typname'] }
|
18
|
-
ranges, nodes = nodes.partition { |row| row['typtype'] == 'r' }
|
19
|
-
enums, nodes = nodes.partition { |row| row['typtype'] == 'e' }
|
20
|
-
domains, nodes = nodes.partition { |row| row['typtype'] == 'd' }
|
21
|
-
arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' }
|
22
|
-
composites, nodes = nodes.partition { |row| row['typelem'] !=
|
18
|
+
ranges, nodes = nodes.partition { |row| row['typtype'] == 'r'.freeze }
|
19
|
+
enums, nodes = nodes.partition { |row| row['typtype'] == 'e'.freeze }
|
20
|
+
domains, nodes = nodes.partition { |row| row['typtype'] == 'd'.freeze }
|
21
|
+
arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in'.freeze }
|
22
|
+
composites, nodes = nodes.partition { |row| row['typelem'].to_i != 0 }
|
23
23
|
|
24
24
|
mapped.each { |row| register_mapped_type(row) }
|
25
25
|
enums.each { |row| register_enum_type(row) }
|
@@ -29,6 +29,18 @@ module ActiveRecord
|
|
29
29
|
composites.each { |row| register_composite_type(row) }
|
30
30
|
end
|
31
31
|
|
32
|
+
def query_conditions_for_initial_load(type_map)
|
33
|
+
known_type_names = type_map.keys.map { |n| "'#{n}'" }
|
34
|
+
known_type_types = %w('r' 'e' 'd')
|
35
|
+
<<-SQL % [known_type_names.join(", "), known_type_types.join(", ")]
|
36
|
+
WHERE
|
37
|
+
t.typname IN (%s)
|
38
|
+
OR t.typtype IN (%s)
|
39
|
+
OR t.typinput = 'array_in(cstring,oid,integer)'::regprocedure
|
40
|
+
OR t.typelem != 0
|
41
|
+
SQL
|
42
|
+
end
|
43
|
+
|
32
44
|
private
|
33
45
|
def register_mapped_type(row)
|
34
46
|
alias_type row['oid'], row['typname']
|
@@ -76,15 +76,15 @@ module ActiveRecord
|
|
76
76
|
column(name, :point, options)
|
77
77
|
end
|
78
78
|
|
79
|
-
def bit(name, options)
|
79
|
+
def bit(name, options = {})
|
80
80
|
column(name, :bit, options)
|
81
81
|
end
|
82
82
|
|
83
|
-
def bit_varying(name, options)
|
83
|
+
def bit_varying(name, options = {})
|
84
84
|
column(name, :bit_varying, options)
|
85
85
|
end
|
86
86
|
|
87
|
-
def money(name, options)
|
87
|
+
def money(name, options = {})
|
88
88
|
column(name, :money, options)
|
89
89
|
end
|
90
90
|
end
|
@@ -86,7 +86,7 @@ module ActiveRecord
|
|
86
86
|
execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
|
87
87
|
end
|
88
88
|
|
89
|
-
# Returns the list of all tables in the schema search path
|
89
|
+
# Returns the list of all tables in the schema search path.
|
90
90
|
def tables(name = nil)
|
91
91
|
query(<<-SQL, 'SCHEMA').map { |row| row[0] }
|
92
92
|
SELECT tablename
|
@@ -95,6 +95,16 @@ module ActiveRecord
|
|
95
95
|
SQL
|
96
96
|
end
|
97
97
|
|
98
|
+
def data_sources # :nodoc
|
99
|
+
select_values(<<-SQL, 'SCHEMA')
|
100
|
+
SELECT c.relname
|
101
|
+
FROM pg_class c
|
102
|
+
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
|
103
|
+
WHERE c.relkind IN ('r', 'v','m') -- (r)elation/table, (v)iew, (m)aterialized view
|
104
|
+
AND n.nspname = ANY (current_schemas(false))
|
105
|
+
SQL
|
106
|
+
end
|
107
|
+
|
98
108
|
# Returns true if table exists.
|
99
109
|
# If the schema is not specified as part of +name+ then it will only find tables within
|
100
110
|
# the current schema search path (regardless of permissions to access tables in other schemas)
|
@@ -111,6 +121,7 @@ module ActiveRecord
|
|
111
121
|
AND n.nspname = #{name.schema ? "'#{name.schema}'" : 'ANY (current_schemas(false))'}
|
112
122
|
SQL
|
113
123
|
end
|
124
|
+
alias data_source_exists? table_exists?
|
114
125
|
|
115
126
|
def drop_table(table_name, options = {})
|
116
127
|
execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
|
@@ -386,15 +397,15 @@ module ActiveRecord
|
|
386
397
|
|
387
398
|
# Returns just a table's primary key
|
388
399
|
def primary_key(table)
|
389
|
-
|
400
|
+
pks = exec_query(<<-end_sql, 'SCHEMA').rows
|
390
401
|
SELECT attr.attname
|
391
402
|
FROM pg_attribute attr
|
392
|
-
INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey
|
403
|
+
INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = any(cons.conkey)
|
393
404
|
WHERE cons.contype = 'p'
|
394
405
|
AND cons.conrelid = '#{quote_table_name(table)}'::regclass
|
395
406
|
end_sql
|
396
|
-
|
397
|
-
|
407
|
+
return nil unless pks.count == 1
|
408
|
+
pks[0][0]
|
398
409
|
end
|
399
410
|
|
400
411
|
# Renames a table.
|
@@ -418,9 +429,7 @@ module ActiveRecord
|
|
418
429
|
rename_table_indexes(table_name, new_name)
|
419
430
|
end
|
420
431
|
|
421
|
-
|
422
|
-
# See TableDefinition#column for details of the options you can use.
|
423
|
-
def add_column(table_name, column_name, type, options = {})
|
432
|
+
def add_column(table_name, column_name, type, options = {}) #:nodoc:
|
424
433
|
clear_cache!
|
425
434
|
super
|
426
435
|
end
|
@@ -468,7 +477,7 @@ module ActiveRecord
|
|
468
477
|
end
|
469
478
|
|
470
479
|
# Renames a column in a table.
|
471
|
-
def rename_column(table_name, column_name, new_column_name)
|
480
|
+
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
472
481
|
clear_cache!
|
473
482
|
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
|
474
483
|
rename_column_indexes(table_name, column_name, new_column_name)
|
@@ -484,9 +493,8 @@ module ActiveRecord
|
|
484
493
|
end
|
485
494
|
|
486
495
|
def rename_index(table_name, old_name, new_name)
|
487
|
-
|
488
|
-
|
489
|
-
end
|
496
|
+
validate_index_length!(table_name, new_name)
|
497
|
+
|
490
498
|
execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
|
491
499
|
end
|
492
500
|
|
@@ -555,7 +563,7 @@ module ActiveRecord
|
|
555
563
|
when 1, 2; 'smallint'
|
556
564
|
when 3, 4; 'integer'
|
557
565
|
when 5..8; 'bigint'
|
558
|
-
else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with
|
566
|
+
else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with scale 0 instead.")
|
559
567
|
end
|
560
568
|
when 'datetime'
|
561
569
|
return super unless precision
|
@@ -64,7 +64,7 @@ module ActiveRecord
|
|
64
64
|
# <tt>SET client_min_messages TO <min_messages></tt> call on the connection.
|
65
65
|
# * <tt>:variables</tt> - An optional hash of additional parameters that
|
66
66
|
# will be used in <tt>SET SESSION key = val</tt> calls on the connection.
|
67
|
-
# * <tt>:insert_returning</tt> - An optional boolean to control the use
|
67
|
+
# * <tt>:insert_returning</tt> - An optional boolean to control the use of <tt>RETURNING</tt> for <tt>INSERT</tt> statements
|
68
68
|
# defaults to true.
|
69
69
|
#
|
70
70
|
# Any further options are used as connection parameters to libpq. See
|
@@ -308,12 +308,8 @@ module ActiveRecord
|
|
308
308
|
true
|
309
309
|
end
|
310
310
|
|
311
|
-
# Enable standard-conforming strings if available.
|
312
311
|
def set_standard_conforming_strings
|
313
|
-
|
314
|
-
execute('SET standard_conforming_strings = on', 'SCHEMA') rescue nil
|
315
|
-
ensure
|
316
|
-
self.client_min_messages = old
|
312
|
+
execute('SET standard_conforming_strings = on', 'SCHEMA')
|
317
313
|
end
|
318
314
|
|
319
315
|
def supports_ddl_transactions?
|
@@ -445,8 +441,8 @@ module ActiveRecord
|
|
445
441
|
|
446
442
|
def initialize_type_map(m) # :nodoc:
|
447
443
|
register_class_with_limit m, 'int2', OID::Integer
|
448
|
-
m
|
449
|
-
m
|
444
|
+
register_class_with_limit m, 'int4', OID::Integer
|
445
|
+
register_class_with_limit m, 'int8', OID::Integer
|
450
446
|
m.alias_type 'oid', 'int2'
|
451
447
|
m.register_type 'float4', OID::Float.new
|
452
448
|
m.alias_type 'float8', 'float4'
|
@@ -556,6 +552,8 @@ module ActiveRecord
|
|
556
552
|
end
|
557
553
|
|
558
554
|
def load_additional_types(type_map, oids = nil) # :nodoc:
|
555
|
+
initializer = OID::TypeMapInitializer.new(type_map)
|
556
|
+
|
559
557
|
if supports_ranges?
|
560
558
|
query = <<-SQL
|
561
559
|
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
|
@@ -571,11 +569,13 @@ module ActiveRecord
|
|
571
569
|
|
572
570
|
if oids
|
573
571
|
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
572
|
+
else
|
573
|
+
query += initializer.query_conditions_for_initial_load(type_map)
|
574
574
|
end
|
575
575
|
|
576
|
-
|
577
|
-
|
578
|
-
|
576
|
+
execute_and_clear(query, 'SCHEMA', []) do |records|
|
577
|
+
initializer.run(records)
|
578
|
+
end
|
579
579
|
end
|
580
580
|
|
581
581
|
FEATURE_NOT_SUPPORTED = "0A000" #:nodoc:
|
@@ -673,7 +673,7 @@ module ActiveRecord
|
|
673
673
|
self.client_min_messages = @config[:min_messages] || 'warning'
|
674
674
|
self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]
|
675
675
|
|
676
|
-
# Use standard-conforming strings
|
676
|
+
# Use standard-conforming strings so we don't have to do the E'...' dance.
|
677
677
|
set_standard_conforming_strings
|
678
678
|
|
679
679
|
# If using Active Record's time zone support configure the connection to return
|
@@ -50,16 +50,6 @@ module ActiveRecord
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
class SQLite3String < Type::String # :nodoc:
|
54
|
-
def type_cast_for_database(value)
|
55
|
-
if value.is_a?(::String) && value.encoding == Encoding::ASCII_8BIT
|
56
|
-
value.encode(Encoding::UTF_8)
|
57
|
-
else
|
58
|
-
super
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
53
|
# The SQLite3 adapter works SQLite 3.6.16 or newer
|
64
54
|
# with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
|
65
55
|
#
|
@@ -84,18 +74,6 @@ module ActiveRecord
|
|
84
74
|
boolean: { name: "boolean" }
|
85
75
|
}
|
86
76
|
|
87
|
-
class Version
|
88
|
-
include Comparable
|
89
|
-
|
90
|
-
def initialize(version_string)
|
91
|
-
@version = version_string.split('.').map { |v| v.to_i }
|
92
|
-
end
|
93
|
-
|
94
|
-
def <=>(version_string)
|
95
|
-
@version <=> version_string.split('.').map { |v| v.to_i }
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
77
|
class StatementPool < ConnectionAdapters::StatementPool
|
100
78
|
def initialize(connection, max)
|
101
79
|
super
|
@@ -239,6 +217,12 @@ module ActiveRecord
|
|
239
217
|
case value
|
240
218
|
when BigDecimal
|
241
219
|
value.to_f
|
220
|
+
when String
|
221
|
+
if value.encoding == Encoding::ASCII_8BIT
|
222
|
+
super(value.encode(Encoding::UTF_8))
|
223
|
+
else
|
224
|
+
super
|
225
|
+
end
|
242
226
|
else
|
243
227
|
super
|
244
228
|
end
|
@@ -361,7 +345,7 @@ module ActiveRecord
|
|
361
345
|
log('commit transaction',nil) { @connection.commit }
|
362
346
|
end
|
363
347
|
|
364
|
-
def
|
348
|
+
def exec_rollback_db_transaction #:nodoc:
|
365
349
|
log('rollback transaction',nil) { @connection.rollback }
|
366
350
|
end
|
367
351
|
|
@@ -379,10 +363,12 @@ module ActiveRecord
|
|
379
363
|
row['name']
|
380
364
|
end
|
381
365
|
end
|
366
|
+
alias data_sources tables
|
382
367
|
|
383
368
|
def table_exists?(table_name)
|
384
369
|
table_name && tables(nil, table_name).any?
|
385
370
|
end
|
371
|
+
alias data_source_exists? table_exists?
|
386
372
|
|
387
373
|
# Returns an array of +Column+ objects for the table specified by +table_name+.
|
388
374
|
def columns(table_name) #:nodoc:
|
@@ -428,10 +414,9 @@ module ActiveRecord
|
|
428
414
|
end
|
429
415
|
|
430
416
|
def primary_key(table_name) #:nodoc:
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
column && column['name']
|
417
|
+
pks = table_structure(table_name).select { |f| f['pk'] > 0 }
|
418
|
+
return nil unless pks.count == 1
|
419
|
+
pks[0]['name']
|
435
420
|
end
|
436
421
|
|
437
422
|
def remove_index!(table_name, index_name) #:nodoc:
|
@@ -509,7 +494,6 @@ module ActiveRecord
|
|
509
494
|
def initialize_type_map(m)
|
510
495
|
super
|
511
496
|
m.register_type(/binary/i, SQLite3Binary.new)
|
512
|
-
register_class_with_limit m, %r(char)i, SQLite3String
|
513
497
|
end
|
514
498
|
|
515
499
|
def table_structure(table_name)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionHandling
|
3
|
-
RAILS_ENV = -> { (Rails.env if defined?(Rails)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] }
|
3
|
+
RAILS_ENV = -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] }
|
4
4
|
DEFAULT_ENV = -> { RAILS_ENV.call || "default_env" }
|
5
5
|
|
6
6
|
# Establishes the connection to the database. Accepts a hash as input where
|
data/lib/active_record/core.rb
CHANGED
@@ -114,16 +114,16 @@ module ActiveRecord
|
|
114
114
|
super
|
115
115
|
end
|
116
116
|
|
117
|
-
def initialize_find_by_cache
|
117
|
+
def initialize_find_by_cache # :nodoc:
|
118
118
|
self.find_by_statement_cache = {}.extend(Mutex_m)
|
119
119
|
end
|
120
120
|
|
121
|
-
def inherited(child_class)
|
121
|
+
def inherited(child_class) # :nodoc:
|
122
122
|
child_class.initialize_find_by_cache
|
123
123
|
super
|
124
124
|
end
|
125
125
|
|
126
|
-
def find(*ids)
|
126
|
+
def find(*ids) # :nodoc:
|
127
127
|
# We don't have cache keys for this stuff yet
|
128
128
|
return super unless ids.length == 1
|
129
129
|
# Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
|
@@ -131,6 +131,7 @@ module ActiveRecord
|
|
131
131
|
return super if block_given? ||
|
132
132
|
primary_key.nil? ||
|
133
133
|
default_scopes.any? ||
|
134
|
+
current_scope ||
|
134
135
|
columns_hash.include?(inheritance_column) ||
|
135
136
|
ids.first.kind_of?(Array)
|
136
137
|
|
@@ -158,7 +159,7 @@ module ActiveRecord
|
|
158
159
|
raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
|
159
160
|
end
|
160
161
|
|
161
|
-
def find_by(*args)
|
162
|
+
def find_by(*args) # :nodoc:
|
162
163
|
return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any?
|
163
164
|
return super if default_scopes.any?
|
164
165
|
|
@@ -191,11 +192,11 @@ module ActiveRecord
|
|
191
192
|
end
|
192
193
|
end
|
193
194
|
|
194
|
-
def find_by!(*args)
|
195
|
+
def find_by!(*args) # :nodoc:
|
195
196
|
find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}")
|
196
197
|
end
|
197
198
|
|
198
|
-
def initialize_generated_modules
|
199
|
+
def initialize_generated_modules # :nodoc:
|
199
200
|
generated_association_methods
|
200
201
|
end
|
201
202
|
|
@@ -270,11 +271,11 @@ module ActiveRecord
|
|
270
271
|
# User.new(first_name: 'Jamie')
|
271
272
|
def initialize(attributes = nil, options = {})
|
272
273
|
@attributes = self.class._default_attributes.dup
|
274
|
+
self.class.define_attribute_methods
|
273
275
|
|
274
276
|
init_internals
|
275
277
|
initialize_internals_callback
|
276
278
|
|
277
|
-
self.class.define_attribute_methods
|
278
279
|
# +options+ argument is only needed to make protected_attributes gem easier to hook.
|
279
280
|
# Remove it when we drop support to this gem.
|
280
281
|
init_attributes(attributes, options) if attributes
|
@@ -283,17 +284,22 @@ module ActiveRecord
|
|
283
284
|
_run_initialize_callbacks
|
284
285
|
end
|
285
286
|
|
286
|
-
# Initialize an empty model object from +coder+. +coder+
|
287
|
-
# the
|
288
|
-
#
|
287
|
+
# Initialize an empty model object from +coder+. +coder+ should be
|
288
|
+
# the result of previously encoding an Active Record model, using
|
289
|
+
# `encode_with`
|
289
290
|
#
|
290
291
|
# class Post < ActiveRecord::Base
|
291
292
|
# end
|
292
293
|
#
|
294
|
+
# old_post = Post.new(title: "hello world")
|
295
|
+
# coder = {}
|
296
|
+
# old_post.encode_with(coder)
|
297
|
+
#
|
293
298
|
# post = Post.allocate
|
294
|
-
# post.init_with(
|
299
|
+
# post.init_with(coder)
|
295
300
|
# post.title # => 'hello world'
|
296
301
|
def init_with(coder)
|
302
|
+
coder = LegacyYamlAdapter.convert(self.class, coder)
|
297
303
|
@attributes = coder['attributes']
|
298
304
|
|
299
305
|
init_internals
|
@@ -367,6 +373,7 @@ module ActiveRecord
|
|
367
373
|
coder['raw_attributes'] = attributes_before_type_cast
|
368
374
|
coder['attributes'] = @attributes
|
369
375
|
coder['new_record'] = new_record?
|
376
|
+
coder['active_record_yaml_version'] = 0
|
370
377
|
end
|
371
378
|
|
372
379
|
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
@@ -452,6 +459,7 @@ module ActiveRecord
|
|
452
459
|
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from `pp record`
|
453
460
|
# when pp is required.
|
454
461
|
def pretty_print(pp)
|
462
|
+
return super if custom_inspect_method_defined?
|
455
463
|
pp.object_address_group(self) do
|
456
464
|
if defined?(@attributes) && @attributes
|
457
465
|
column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
|
@@ -477,16 +485,16 @@ module ActiveRecord
|
|
477
485
|
Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
|
478
486
|
end
|
479
487
|
|
488
|
+
private
|
489
|
+
|
480
490
|
def set_transaction_state(state) # :nodoc:
|
481
491
|
@transaction_state = state
|
482
492
|
end
|
483
493
|
|
484
494
|
def has_transactional_callbacks? # :nodoc:
|
485
|
-
!_rollback_callbacks.empty? || !_commit_callbacks.empty?
|
495
|
+
!_rollback_callbacks.empty? || !_commit_callbacks.empty?
|
486
496
|
end
|
487
497
|
|
488
|
-
private
|
489
|
-
|
490
498
|
# Updates the attributes on this particular ActiveRecord object so that
|
491
499
|
# if it is associated with a transaction, then the state of the AR object
|
492
500
|
# will be updated to reflect the current state of the transaction
|
@@ -509,6 +517,8 @@ module ActiveRecord
|
|
509
517
|
end
|
510
518
|
|
511
519
|
def update_attributes_from_transaction_state(transaction_state, depth)
|
520
|
+
@reflects_state = [false] if depth == 0
|
521
|
+
|
512
522
|
if transaction_state && transaction_state.finalized? && !has_transactional_callbacks?
|
513
523
|
unless @reflects_state[depth]
|
514
524
|
restore_transaction_record_state if transaction_state.rolledback?
|
@@ -545,7 +555,6 @@ module ActiveRecord
|
|
545
555
|
@txn = nil
|
546
556
|
@_start_transaction_state = {}
|
547
557
|
@transaction_state = nil
|
548
|
-
@reflects_state = [false]
|
549
558
|
end
|
550
559
|
|
551
560
|
def initialize_internals_callback
|
@@ -562,5 +571,9 @@ module ActiveRecord
|
|
562
571
|
@attributes = @attributes.dup
|
563
572
|
end
|
564
573
|
end
|
574
|
+
|
575
|
+
def custom_inspect_method_defined?
|
576
|
+
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
577
|
+
end
|
565
578
|
end
|
566
579
|
end
|