activerecord 5.2.0.beta2 → 5.2.0.rc1
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 +5 -5
- data/CHANGELOG.md +231 -2
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_record.rb +1 -1
- data/lib/active_record/aggregations.rb +4 -5
- data/lib/active_record/association_relation.rb +2 -2
- data/lib/active_record/associations.rb +18 -12
- data/lib/active_record/associations/alias_tracker.rb +2 -10
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/belongs_to_association.rb +9 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -6
- data/lib/active_record/associations/builder/association.rb +2 -2
- data/lib/active_record/associations/builder/belongs_to.rb +7 -3
- data/lib/active_record/associations/collection_association.rb +2 -2
- data/lib/active_record/associations/collection_proxy.rb +1 -1
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +4 -17
- data/lib/active_record/associations/has_one_through_association.rb +5 -6
- data/lib/active_record/associations/preloader.rb +1 -1
- data/lib/active_record/associations/preloader/association.rb +2 -2
- data/lib/active_record/associations/through_association.rb +22 -9
- data/lib/active_record/attribute_methods.rb +1 -5
- data/lib/active_record/attribute_methods/dirty.rb +2 -4
- data/lib/active_record/attributes.rb +1 -1
- data/lib/active_record/autosave_association.rb +3 -0
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/collection_cache_key.rb +5 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +57 -21
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +20 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +55 -15
- data/lib/active_record/connection_adapters/abstract_adapter.rb +19 -6
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +55 -64
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +8 -1
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +0 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +21 -6
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +9 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +13 -4
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +170 -48
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +15 -5
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +63 -18
- data/lib/active_record/core.rb +12 -3
- data/lib/active_record/enum.rb +2 -0
- data/lib/active_record/fixtures.rb +28 -37
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +3 -4
- data/lib/active_record/log_subscriber.rb +41 -0
- data/lib/active_record/migration.rb +138 -120
- data/lib/active_record/migration/compatibility.rb +20 -0
- data/lib/active_record/model_schema.rb +19 -16
- data/lib/active_record/persistence.rb +8 -11
- data/lib/active_record/railtie.rb +7 -2
- data/lib/active_record/railties/databases.rake +8 -11
- data/lib/active_record/reflection.rb +10 -13
- data/lib/active_record/relation.rb +27 -17
- data/lib/active_record/relation/calculations.rb +17 -12
- data/lib/active_record/relation/finder_methods.rb +30 -37
- data/lib/active_record/relation/merger.rb +30 -2
- data/lib/active_record/relation/predicate_builder.rb +12 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +14 -24
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +16 -2
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/sanitization.rb +130 -128
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +12 -3
- data/lib/active_record/scoping/named.rb +6 -0
- data/lib/active_record/store.rb +1 -1
- data/lib/active_record/table_metadata.rb +10 -3
- data/lib/active_record/tasks/database_tasks.rb +4 -4
- data/lib/active_record/type_caster/map.rb +1 -1
- metadata +9 -9
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Make sure we're using pg high enough for type casts and Ruby 2.2+ compatibility
|
4
|
-
gem "pg", "
|
4
|
+
gem "pg", ">= 0.18", "< 2.0"
|
5
5
|
require "pg"
|
6
6
|
|
7
7
|
require "active_record/connection_adapters/abstract_adapter"
|
@@ -122,6 +122,10 @@ module ActiveRecord
|
|
122
122
|
include PostgreSQL::SchemaStatements
|
123
123
|
include PostgreSQL::DatabaseStatements
|
124
124
|
|
125
|
+
def supports_bulk_alter?
|
126
|
+
true
|
127
|
+
end
|
128
|
+
|
125
129
|
def supports_index_sort_order?
|
126
130
|
true
|
127
131
|
end
|
@@ -142,6 +146,10 @@ module ActiveRecord
|
|
142
146
|
true
|
143
147
|
end
|
144
148
|
|
149
|
+
def supports_validate_constraints?
|
150
|
+
true
|
151
|
+
end
|
152
|
+
|
145
153
|
def supports_views?
|
146
154
|
true
|
147
155
|
end
|
@@ -166,7 +174,7 @@ module ActiveRecord
|
|
166
174
|
{ concurrently: "CONCURRENTLY" }
|
167
175
|
end
|
168
176
|
|
169
|
-
class StatementPool < ConnectionAdapters::StatementPool
|
177
|
+
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
170
178
|
def initialize(connection, max)
|
171
179
|
super(max)
|
172
180
|
@connection = connection
|
@@ -182,7 +190,6 @@ module ActiveRecord
|
|
182
190
|
end
|
183
191
|
|
184
192
|
private
|
185
|
-
|
186
193
|
def dealloc(key)
|
187
194
|
@connection.query "DEALLOCATE #{key}" if connection_active?
|
188
195
|
rescue PG::Error
|
@@ -274,7 +281,7 @@ module ActiveRecord
|
|
274
281
|
end
|
275
282
|
|
276
283
|
def discard! # :nodoc:
|
277
|
-
@connection.socket_io.reopen(IO::NULL)
|
284
|
+
@connection.socket_io.reopen(IO::NULL) rescue nil
|
278
285
|
@connection = nil
|
279
286
|
end
|
280
287
|
|
@@ -311,6 +318,10 @@ module ActiveRecord
|
|
311
318
|
postgresql_version >= 90300
|
312
319
|
end
|
313
320
|
|
321
|
+
def supports_foreign_tables?
|
322
|
+
postgresql_version >= 90300
|
323
|
+
end
|
324
|
+
|
314
325
|
def supports_pgcrypto_uuid?
|
315
326
|
postgresql_version >= 90400
|
316
327
|
end
|
@@ -387,7 +398,6 @@ module ActiveRecord
|
|
387
398
|
end
|
388
399
|
|
389
400
|
private
|
390
|
-
|
391
401
|
# See https://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
392
402
|
VALUE_LIMIT_VIOLATION = "22001"
|
393
403
|
NUMERIC_VALUE_OUT_OF_RANGE = "22003"
|
@@ -28,7 +28,7 @@ module ActiveRecord
|
|
28
28
|
coder["columns_hash"] = @columns_hash
|
29
29
|
coder["primary_keys"] = @primary_keys
|
30
30
|
coder["data_sources"] = @data_sources
|
31
|
-
coder["version"] =
|
31
|
+
coder["version"] = connection.migration_context.current_version
|
32
32
|
end
|
33
33
|
|
34
34
|
def init_with(coder)
|
@@ -100,7 +100,7 @@ module ActiveRecord
|
|
100
100
|
|
101
101
|
def marshal_dump
|
102
102
|
# if we get current version during initialization, it happens stack over flow.
|
103
|
-
@version =
|
103
|
+
@version = connection.migration_context.current_version
|
104
104
|
[@version, @columns, @columns_hash, @primary_keys, @data_sources]
|
105
105
|
end
|
106
106
|
|
@@ -60,7 +60,7 @@ module ActiveRecord
|
|
60
60
|
include SQLite3::SchemaStatements
|
61
61
|
|
62
62
|
NATIVE_DATABASE_TYPES = {
|
63
|
-
primary_key: "
|
63
|
+
primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
|
64
64
|
string: { name: "varchar" },
|
65
65
|
text: { name: "text" },
|
66
66
|
integer: { name: "integer" },
|
@@ -70,7 +70,8 @@ module ActiveRecord
|
|
70
70
|
time: { name: "time" },
|
71
71
|
date: { name: "date" },
|
72
72
|
binary: { name: "blob" },
|
73
|
-
boolean: { name: "boolean" }
|
73
|
+
boolean: { name: "boolean" },
|
74
|
+
json: { name: "json" },
|
74
75
|
}
|
75
76
|
|
76
77
|
##
|
@@ -90,9 +91,8 @@ module ActiveRecord
|
|
90
91
|
# Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
|
91
92
|
class_attribute :represent_boolean_as_integer, default: false
|
92
93
|
|
93
|
-
class StatementPool < ConnectionAdapters::StatementPool
|
94
|
+
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
94
95
|
private
|
95
|
-
|
96
96
|
def dealloc(stmt)
|
97
97
|
stmt[:stmt].close unless stmt[:stmt].closed?
|
98
98
|
end
|
@@ -101,7 +101,7 @@ module ActiveRecord
|
|
101
101
|
def initialize(connection, logger, connection_options, config)
|
102
102
|
super(connection, logger, config)
|
103
103
|
|
104
|
-
@active =
|
104
|
+
@active = true
|
105
105
|
@statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
|
106
106
|
|
107
107
|
configure_connection
|
@@ -135,12 +135,16 @@ module ActiveRecord
|
|
135
135
|
true
|
136
136
|
end
|
137
137
|
|
138
|
+
def supports_json?
|
139
|
+
true
|
140
|
+
end
|
141
|
+
|
138
142
|
def supports_multi_insert?
|
139
143
|
sqlite_version >= "3.7.11"
|
140
144
|
end
|
141
145
|
|
142
146
|
def active?
|
143
|
-
@active
|
147
|
+
@active
|
144
148
|
end
|
145
149
|
|
146
150
|
# Disconnects from the database if already connected. Otherwise, this
|
@@ -286,19 +290,18 @@ module ActiveRecord
|
|
286
290
|
rename_table_indexes(table_name, new_name)
|
287
291
|
end
|
288
292
|
|
289
|
-
|
290
|
-
|
291
|
-
def valid_alter_table_type?(type)
|
292
|
-
type.to_sym != :primary_key
|
293
|
+
def valid_alter_table_type?(type, options = {})
|
294
|
+
!invalid_alter_table_type?(type, options)
|
293
295
|
end
|
296
|
+
deprecate :valid_alter_table_type?
|
294
297
|
|
295
298
|
def add_column(table_name, column_name, type, options = {}) #:nodoc:
|
296
|
-
if
|
297
|
-
super(table_name, column_name, type, options)
|
298
|
-
else
|
299
|
+
if invalid_alter_table_type?(type, options)
|
299
300
|
alter_table(table_name) do |definition|
|
300
301
|
definition.column(column_name, type, options)
|
301
302
|
end
|
303
|
+
else
|
304
|
+
super
|
302
305
|
end
|
303
306
|
end
|
304
307
|
|
@@ -364,12 +367,30 @@ module ActiveRecord
|
|
364
367
|
end
|
365
368
|
|
366
369
|
def insert_fixtures(rows, table_name)
|
367
|
-
|
368
|
-
|
370
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
371
|
+
`insert_fixtures` is deprecated and will be removed in the next version of Rails.
|
372
|
+
Consider using `insert_fixtures_set` for performance improvement.
|
373
|
+
MSG
|
374
|
+
insert_fixtures_set(table_name => rows)
|
375
|
+
end
|
376
|
+
|
377
|
+
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
378
|
+
disable_referential_integrity do
|
379
|
+
transaction(requires_new: true) do
|
380
|
+
tables_to_delete.each { |table| delete "DELETE FROM #{quote_table_name(table)}", "Fixture Delete" }
|
381
|
+
|
382
|
+
fixture_set.each do |table_name, rows|
|
383
|
+
rows.each { |row| insert_fixture(row, table_name) }
|
384
|
+
end
|
385
|
+
end
|
369
386
|
end
|
370
387
|
end
|
371
388
|
|
372
389
|
private
|
390
|
+
def initialize_type_map(m = type_map)
|
391
|
+
super
|
392
|
+
register_class_with_limit m, %r(int)i, SQLite3Integer
|
393
|
+
end
|
373
394
|
|
374
395
|
def table_structure(table_name)
|
375
396
|
structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", "SCHEMA")
|
@@ -378,6 +399,12 @@ module ActiveRecord
|
|
378
399
|
end
|
379
400
|
alias column_definitions table_structure
|
380
401
|
|
402
|
+
# See: https://www.sqlite.org/lang_altertable.html
|
403
|
+
# SQLite has an additional restriction on the ALTER TABLE statement
|
404
|
+
def invalid_alter_table_type?(type, options)
|
405
|
+
type.to_sym == :primary_key || options[:primary_key]
|
406
|
+
end
|
407
|
+
|
381
408
|
def alter_table(table_name, options = {})
|
382
409
|
altered_table_name = "a#{table_name}"
|
383
410
|
caller = lambda { |definition| yield definition if block_given? }
|
@@ -399,18 +426,21 @@ module ActiveRecord
|
|
399
426
|
options[:id] = false
|
400
427
|
create_table(to, options) do |definition|
|
401
428
|
@definition = definition
|
402
|
-
|
429
|
+
if from_primary_key.is_a?(Array)
|
430
|
+
@definition.primary_keys from_primary_key
|
431
|
+
end
|
403
432
|
columns(from).each do |column|
|
404
433
|
column_name = options[:rename] ?
|
405
434
|
(options[:rename][column.name] ||
|
406
435
|
options[:rename][column.name.to_sym] ||
|
407
436
|
column.name) : column.name
|
408
|
-
next if column_name == from_primary_key
|
409
437
|
|
410
438
|
@definition.column(column_name, column.type,
|
411
439
|
limit: column.limit, default: column.default,
|
412
440
|
precision: column.precision, scale: column.scale,
|
413
|
-
null: column.null, collation: column.collation
|
441
|
+
null: column.null, collation: column.collation,
|
442
|
+
primary_key: column_name == from_primary_key
|
443
|
+
)
|
414
444
|
end
|
415
445
|
yield @definition if block_given?
|
416
446
|
end
|
@@ -423,6 +453,9 @@ module ActiveRecord
|
|
423
453
|
def copy_table_indexes(from, to, rename = {})
|
424
454
|
indexes(from).each do |index|
|
425
455
|
name = index.name
|
456
|
+
# indexes sqlite creates for internal use start with `sqlite_` and
|
457
|
+
# don't need to be copied
|
458
|
+
next if name.starts_with?("sqlite_")
|
426
459
|
if to == "a#{from}"
|
427
460
|
name = "t#{name}"
|
428
461
|
elsif from == "a#{to}"
|
@@ -438,6 +471,7 @@ module ActiveRecord
|
|
438
471
|
# index name can't be the same
|
439
472
|
opts = { name: name.gsub(/(^|_)(#{from})_/, "\\1#{to}_"), internal: true }
|
440
473
|
opts[:unique] = true if index.unique
|
474
|
+
opts[:where] = index.where if index.where
|
441
475
|
add_index(to, columns, opts)
|
442
476
|
end
|
443
477
|
end
|
@@ -525,6 +559,17 @@ module ActiveRecord
|
|
525
559
|
def configure_connection
|
526
560
|
execute("PRAGMA foreign_keys = ON", "SCHEMA")
|
527
561
|
end
|
562
|
+
|
563
|
+
class SQLite3Integer < Type::Integer # :nodoc:
|
564
|
+
private
|
565
|
+
def _limit
|
566
|
+
# INTEGER storage class can be stored 8 bytes value.
|
567
|
+
# See https://www.sqlite.org/datatype3.html#storage_classes_and_datatypes
|
568
|
+
limit || 8
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
ActiveRecord::Type.register(:integer, SQLite3Integer, adapter: :sqlite3)
|
528
573
|
end
|
529
574
|
ActiveSupport.run_load_hooks(:active_record_sqlite3adapter, SQLite3Adapter)
|
530
575
|
end
|
data/lib/active_record/core.rb
CHANGED
@@ -17,6 +17,13 @@ module ActiveRecord
|
|
17
17
|
# retrieved on both a class and instance level by calling +logger+.
|
18
18
|
mattr_accessor :logger, instance_writer: false
|
19
19
|
|
20
|
+
##
|
21
|
+
# :singleton-method:
|
22
|
+
#
|
23
|
+
# Specifies if the methods calling database queries should be logged below
|
24
|
+
# their relevant queries. Defaults to false.
|
25
|
+
mattr_accessor :verbose_query_logs, instance_writer: false, default: false
|
26
|
+
|
20
27
|
##
|
21
28
|
# Contains the database configuration - as is typically stored in config/database.yml -
|
22
29
|
# as a Hash.
|
@@ -274,7 +281,7 @@ module ActiveRecord
|
|
274
281
|
end
|
275
282
|
|
276
283
|
def relation
|
277
|
-
relation = Relation.create(self
|
284
|
+
relation = Relation.create(self)
|
278
285
|
|
279
286
|
if finder_needs_type_condition? && !ignore_default_scope?
|
280
287
|
relation.where!(type_condition)
|
@@ -375,8 +382,10 @@ module ActiveRecord
|
|
375
382
|
|
376
383
|
_run_initialize_callbacks
|
377
384
|
|
378
|
-
@new_record
|
379
|
-
@destroyed
|
385
|
+
@new_record = true
|
386
|
+
@destroyed = false
|
387
|
+
@_start_transaction_state = {}
|
388
|
+
@transaction_state = nil
|
380
389
|
|
381
390
|
super
|
382
391
|
end
|
data/lib/active_record/enum.rb
CHANGED
@@ -221,6 +221,8 @@ module ActiveRecord
|
|
221
221
|
def detect_enum_conflict!(enum_name, method_name, klass_method = false)
|
222
222
|
if klass_method && dangerous_class_method?(method_name)
|
223
223
|
raise_conflict_error(enum_name, method_name, type: "class")
|
224
|
+
elsif klass_method && method_defined_within?(method_name, Relation)
|
225
|
+
raise_conflict_error(enum_name, method_name, type: "class", source: Relation.name)
|
224
226
|
elsif !klass_method && dangerous_attribute_method?(method_name)
|
225
227
|
raise_conflict_error(enum_name, method_name)
|
226
228
|
elsif !klass_method && method_defined_within?(method_name, _enum_methods_module, Module)
|
@@ -169,13 +169,13 @@ module ActiveRecord
|
|
169
169
|
# self.use_transactional_tests = true
|
170
170
|
#
|
171
171
|
# test "godzilla" do
|
172
|
-
#
|
172
|
+
# assert_not_empty Foo.all
|
173
173
|
# Foo.destroy_all
|
174
|
-
#
|
174
|
+
# assert_empty Foo.all
|
175
175
|
# end
|
176
176
|
#
|
177
177
|
# test "godzilla aftermath" do
|
178
|
-
#
|
178
|
+
# assert_not_empty Foo.all
|
179
179
|
# end
|
180
180
|
# end
|
181
181
|
#
|
@@ -540,47 +540,38 @@ module ActiveRecord
|
|
540
540
|
}
|
541
541
|
|
542
542
|
unless files_to_read.empty?
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
end
|
555
|
-
|
556
|
-
update_all_loaded_fixtures fixtures_map
|
557
|
-
|
558
|
-
connection.transaction(requires_new: true) do
|
559
|
-
deleted_tables = Hash.new { |h, k| h[k] = Set.new }
|
560
|
-
fixture_sets.each do |fs|
|
561
|
-
conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection
|
562
|
-
table_rows = fs.table_rows
|
543
|
+
fixtures_map = {}
|
544
|
+
|
545
|
+
fixture_sets = files_to_read.map do |fs_name|
|
546
|
+
klass = class_names[fs_name]
|
547
|
+
conn = klass ? klass.connection : connection
|
548
|
+
fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new
|
549
|
+
conn,
|
550
|
+
fs_name,
|
551
|
+
klass,
|
552
|
+
::File.join(fixtures_directory, fs_name))
|
553
|
+
end
|
563
554
|
|
564
|
-
|
565
|
-
|
566
|
-
conn.delete "DELETE FROM #{conn.quote_table_name(table)}", "Fixture Delete"
|
567
|
-
end
|
568
|
-
deleted_tables[conn] << table
|
569
|
-
end
|
555
|
+
update_all_loaded_fixtures fixtures_map
|
556
|
+
fixture_sets_by_connection = fixture_sets.group_by { |fs| fs.model_class ? fs.model_class.connection : connection }
|
570
557
|
|
571
|
-
|
572
|
-
|
573
|
-
end
|
558
|
+
fixture_sets_by_connection.each do |conn, set|
|
559
|
+
table_rows_for_connection = Hash.new { |h, k| h[k] = [] }
|
574
560
|
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
end
|
561
|
+
set.each do |fs|
|
562
|
+
fs.table_rows.each do |table, rows|
|
563
|
+
table_rows_for_connection[table].unshift(*rows)
|
579
564
|
end
|
580
565
|
end
|
566
|
+
conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys)
|
581
567
|
|
582
|
-
|
568
|
+
# Cap primary key sequences to max(pk).
|
569
|
+
if conn.respond_to?(:reset_pk_sequence!)
|
570
|
+
set.each { |fs| conn.reset_pk_sequence!(fs.table_name) }
|
571
|
+
end
|
583
572
|
end
|
573
|
+
|
574
|
+
cache_fixtures(connection, fixtures_map)
|
584
575
|
end
|
585
576
|
cached_fixtures(connection, fixture_set_names)
|
586
577
|
end
|
@@ -47,14 +47,13 @@ module ActiveRecord
|
|
47
47
|
# Determines if one of the attributes passed in is the inheritance column,
|
48
48
|
# and if the inheritance column is attr accessible, it initializes an
|
49
49
|
# instance of the given subclass instead of the base class.
|
50
|
-
def new(
|
50
|
+
def new(attributes = nil, &block)
|
51
51
|
if abstract_class? || self == Base
|
52
52
|
raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
|
53
53
|
end
|
54
54
|
|
55
|
-
attrs = args.first
|
56
55
|
if has_attribute?(inheritance_column)
|
57
|
-
subclass = subclass_from_attributes(
|
56
|
+
subclass = subclass_from_attributes(attributes)
|
58
57
|
|
59
58
|
if subclass.nil? && base_class == self
|
60
59
|
subclass = subclass_from_attributes(column_defaults)
|
@@ -62,7 +61,7 @@ module ActiveRecord
|
|
62
61
|
end
|
63
62
|
|
64
63
|
if subclass && subclass != self
|
65
|
-
subclass.new(
|
64
|
+
subclass.new(attributes, &block)
|
66
65
|
else
|
67
66
|
super
|
68
67
|
end
|
@@ -90,6 +90,47 @@ module ActiveRecord
|
|
90
90
|
def logger
|
91
91
|
ActiveRecord::Base.logger
|
92
92
|
end
|
93
|
+
|
94
|
+
def debug(progname = nil, &block)
|
95
|
+
return unless super
|
96
|
+
|
97
|
+
if ActiveRecord::Base.verbose_query_logs
|
98
|
+
log_query_source
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def log_query_source
|
103
|
+
source_line, line_number = extract_callstack(caller_locations)
|
104
|
+
|
105
|
+
if source_line
|
106
|
+
if defined?(::Rails.root)
|
107
|
+
app_root = "#{::Rails.root.to_s}/".freeze
|
108
|
+
source_line = source_line.sub(app_root, "")
|
109
|
+
end
|
110
|
+
|
111
|
+
logger.debug(" ↳ #{ source_line }:#{ line_number }")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def extract_callstack(callstack)
|
116
|
+
line = callstack.find do |frame|
|
117
|
+
frame.absolute_path && !ignored_callstack(frame.absolute_path)
|
118
|
+
end
|
119
|
+
|
120
|
+
offending_line = line || callstack.first
|
121
|
+
|
122
|
+
[
|
123
|
+
offending_line.path,
|
124
|
+
offending_line.lineno
|
125
|
+
]
|
126
|
+
end
|
127
|
+
|
128
|
+
RAILS_GEM_ROOT = File.expand_path("../../../..", __FILE__) + "/"
|
129
|
+
|
130
|
+
def ignored_callstack(path)
|
131
|
+
path.start_with?(RAILS_GEM_ROOT) ||
|
132
|
+
path.start_with?(RbConfig::CONFIG["rubylibdir"])
|
133
|
+
end
|
93
134
|
end
|
94
135
|
end
|
95
136
|
|