activerecord 6.0.0.beta3 → 6.0.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 +4 -4
- data/CHANGELOG.md +286 -6
- data/README.rdoc +3 -1
- data/lib/active_record.rb +0 -1
- data/lib/active_record/associations.rb +3 -2
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +5 -2
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_proxy.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +4 -11
- data/lib/active_record/associations/preloader.rb +11 -6
- data/lib/active_record/associations/preloader/association.rb +32 -30
- data/lib/active_record/associations/preloader/through_association.rb +48 -28
- data/lib/active_record/attribute_methods.rb +4 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
- data/lib/active_record/attribute_methods/dirty.rb +42 -14
- data/lib/active_record/attribute_methods/primary_key.rb +7 -15
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +3 -9
- data/lib/active_record/attribute_methods/write.rb +6 -12
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +13 -3
- data/lib/active_record/base.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +8 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +84 -61
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +10 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -7
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +70 -14
- data/lib/active_record/connection_adapters/abstract_adapter.rb +56 -11
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +65 -69
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -7
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +4 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +9 -6
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +6 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -30
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +34 -38
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +23 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -27
- data/lib/active_record/connection_adapters/schema_cache.rb +32 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +50 -112
- data/lib/active_record/connection_handling.rb +17 -10
- data/lib/active_record/core.rb +15 -20
- data/lib/active_record/database_configurations.rb +14 -14
- data/lib/active_record/database_configurations/hash_config.rb +11 -11
- data/lib/active_record/database_configurations/url_config.rb +12 -12
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +6 -0
- data/lib/active_record/errors.rb +1 -1
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/insert_all.rb +180 -0
- data/lib/active_record/integration.rb +13 -1
- data/lib/active_record/internal_metadata.rb +5 -1
- data/lib/active_record/locking/optimistic.rb +3 -4
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/migration.rb +25 -18
- data/lib/active_record/migration/command_recorder.rb +28 -14
- data/lib/active_record/migration/compatibility.rb +10 -0
- data/lib/active_record/persistence.rb +206 -13
- data/lib/active_record/querying.rb +17 -12
- data/lib/active_record/railties/databases.rake +68 -6
- data/lib/active_record/reflection.rb +2 -2
- data/lib/active_record/relation.rb +98 -20
- data/lib/active_record/relation/calculations.rb +39 -39
- data/lib/active_record/relation/delegation.rb +22 -30
- data/lib/active_record/relation/finder_methods.rb +3 -9
- data/lib/active_record/relation/merger.rb +7 -16
- data/lib/active_record/relation/query_methods.rb +153 -38
- data/lib/active_record/relation/where_clause.rb +9 -5
- data/lib/active_record/sanitization.rb +3 -2
- data/lib/active_record/schema_dumper.rb +5 -0
- data/lib/active_record/schema_migration.rb +1 -1
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +1 -1
- data/lib/active_record/statement_cache.rb +2 -2
- data/lib/active_record/store.rb +48 -0
- data/lib/active_record/table_metadata.rb +3 -3
- data/lib/active_record/tasks/database_tasks.rb +36 -1
- data/lib/active_record/touch_later.rb +2 -2
- data/lib/active_record/transactions.rb +52 -41
- data/lib/active_record/validations/uniqueness.rb +3 -5
- data/lib/arel/insert_manager.rb +3 -3
- data/lib/arel/nodes.rb +2 -1
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/select_core.rb +16 -12
- data/lib/arel/nodes/unary.rb +1 -0
- data/lib/arel/nodes/values_list.rb +2 -17
- data/lib/arel/select_manager.rb +10 -10
- data/lib/arel/visitors/depth_first.rb +6 -1
- data/lib/arel/visitors/dot.rb +7 -2
- data/lib/arel/visitors/ibm_db.rb +13 -0
- data/lib/arel/visitors/informix.rb +6 -0
- data/lib/arel/visitors/mssql.rb +15 -1
- data/lib/arel/visitors/oracle12.rb +4 -5
- data/lib/arel/visitors/postgresql.rb +4 -10
- data/lib/arel/visitors/to_sql.rb +87 -108
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +12 -11
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/arel/nodes/values.rb +0 -16
@@ -72,7 +72,7 @@ module ActiveRecord
|
|
72
72
|
table = strip_table_name_prefix_and_suffix(table)
|
73
73
|
fk_to_table = strip_table_name_prefix_and_suffix(fk.to_table)
|
74
74
|
fk_to_table == table && options.all? { |k, v| fk.options[k].to_s == v.to_s }
|
75
|
-
end || raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table}")
|
75
|
+
end || raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table || options}")
|
76
76
|
|
77
77
|
foreign_keys.delete(fkey)
|
78
78
|
alter_table(from_table, foreign_keys)
|
@@ -105,7 +105,7 @@ module ActiveRecord
|
|
105
105
|
end
|
106
106
|
|
107
107
|
type_metadata = fetch_type_metadata(field["type"])
|
108
|
-
Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0,
|
108
|
+
Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, collation: field["collation"])
|
109
109
|
end
|
110
110
|
|
111
111
|
def data_source_sql(name = nil, type: nil)
|
@@ -4,12 +4,13 @@ require "active_record/connection_adapters/abstract_adapter"
|
|
4
4
|
require "active_record/connection_adapters/statement_pool"
|
5
5
|
require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
|
6
6
|
require "active_record/connection_adapters/sqlite3/quoting"
|
7
|
+
require "active_record/connection_adapters/sqlite3/database_statements"
|
7
8
|
require "active_record/connection_adapters/sqlite3/schema_creation"
|
8
9
|
require "active_record/connection_adapters/sqlite3/schema_definitions"
|
9
10
|
require "active_record/connection_adapters/sqlite3/schema_dumper"
|
10
11
|
require "active_record/connection_adapters/sqlite3/schema_statements"
|
11
12
|
|
12
|
-
gem "sqlite3", "~> 1.
|
13
|
+
gem "sqlite3", "~> 1.4"
|
13
14
|
require "sqlite3"
|
14
15
|
|
15
16
|
module ActiveRecord
|
@@ -36,8 +37,6 @@ module ActiveRecord
|
|
36
37
|
config.merge(results_as_hash: true)
|
37
38
|
)
|
38
39
|
|
39
|
-
db.busy_timeout(ConnectionAdapters::SQLite3Adapter.type_cast_config_to_integer(config[:timeout])) if config[:timeout]
|
40
|
-
|
41
40
|
ConnectionAdapters::SQLite3Adapter.new(db, logger, nil, config)
|
42
41
|
rescue Errno::ENOENT => error
|
43
42
|
if error.message.include?("No such file or directory")
|
@@ -60,6 +59,7 @@ module ActiveRecord
|
|
60
59
|
|
61
60
|
include SQLite3::Quoting
|
62
61
|
include SQLite3::SchemaStatements
|
62
|
+
include SQLite3::DatabaseStatements
|
63
63
|
|
64
64
|
NATIVE_DATABASE_TYPES = {
|
65
65
|
primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
|
@@ -95,9 +95,6 @@ module ActiveRecord
|
|
95
95
|
|
96
96
|
def initialize(connection, logger, connection_options, config)
|
97
97
|
super(connection, logger, config)
|
98
|
-
|
99
|
-
@active = true
|
100
|
-
@statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
|
101
98
|
configure_connection
|
102
99
|
end
|
103
100
|
|
@@ -114,7 +111,7 @@ module ActiveRecord
|
|
114
111
|
end
|
115
112
|
|
116
113
|
def supports_expression_index?
|
117
|
-
|
114
|
+
database_version >= "3.9.0"
|
118
115
|
end
|
119
116
|
|
120
117
|
def requires_reloading?
|
@@ -137,23 +134,29 @@ module ActiveRecord
|
|
137
134
|
true
|
138
135
|
end
|
139
136
|
|
137
|
+
def supports_insert_on_conflict?
|
138
|
+
database_version >= "3.24.0"
|
139
|
+
end
|
140
|
+
alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
|
141
|
+
alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
|
142
|
+
alias supports_insert_conflict_target? supports_insert_on_conflict?
|
143
|
+
|
140
144
|
def active?
|
141
|
-
|
145
|
+
!@connection.closed?
|
146
|
+
end
|
147
|
+
|
148
|
+
def reconnect!
|
149
|
+
super
|
150
|
+
connect if @connection.closed?
|
142
151
|
end
|
143
152
|
|
144
153
|
# Disconnects from the database if already connected. Otherwise, this
|
145
154
|
# method does nothing.
|
146
155
|
def disconnect!
|
147
156
|
super
|
148
|
-
@active = false
|
149
157
|
@connection.close rescue nil
|
150
158
|
end
|
151
159
|
|
152
|
-
# Clears the prepared statements cache.
|
153
|
-
def clear_cache!
|
154
|
-
@statements.clear
|
155
|
-
end
|
156
|
-
|
157
160
|
def supports_index_sort_order?
|
158
161
|
true
|
159
162
|
end
|
@@ -201,91 +204,11 @@ module ActiveRecord
|
|
201
204
|
#--
|
202
205
|
# DATABASE STATEMENTS ======================================
|
203
206
|
#++
|
204
|
-
|
205
|
-
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(:begin, :commit, :explain, :select, :pragma, :release, :savepoint, :rollback) # :nodoc:
|
206
|
-
private_constant :READ_QUERY
|
207
|
-
|
208
|
-
def write_query?(sql) # :nodoc:
|
209
|
-
!READ_QUERY.match?(sql)
|
210
|
-
end
|
211
|
-
|
212
207
|
def explain(arel, binds = [])
|
213
208
|
sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
|
214
209
|
SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
|
215
210
|
end
|
216
211
|
|
217
|
-
def exec_query(sql, name = nil, binds = [], prepare: false)
|
218
|
-
if preventing_writes? && write_query?(sql)
|
219
|
-
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
220
|
-
end
|
221
|
-
|
222
|
-
materialize_transactions
|
223
|
-
|
224
|
-
type_casted_binds = type_casted_binds(binds)
|
225
|
-
|
226
|
-
log(sql, name, binds, type_casted_binds) do
|
227
|
-
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
228
|
-
# Don't cache statements if they are not prepared
|
229
|
-
unless prepare
|
230
|
-
stmt = @connection.prepare(sql)
|
231
|
-
begin
|
232
|
-
cols = stmt.columns
|
233
|
-
unless without_prepared_statement?(binds)
|
234
|
-
stmt.bind_params(type_casted_binds)
|
235
|
-
end
|
236
|
-
records = stmt.to_a
|
237
|
-
ensure
|
238
|
-
stmt.close
|
239
|
-
end
|
240
|
-
else
|
241
|
-
stmt = @statements[sql] ||= @connection.prepare(sql)
|
242
|
-
cols = stmt.columns
|
243
|
-
stmt.reset!
|
244
|
-
stmt.bind_params(type_casted_binds)
|
245
|
-
records = stmt.to_a
|
246
|
-
end
|
247
|
-
|
248
|
-
ActiveRecord::Result.new(cols, records)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
def exec_delete(sql, name = "SQL", binds = [])
|
254
|
-
exec_query(sql, name, binds)
|
255
|
-
@connection.changes
|
256
|
-
end
|
257
|
-
alias :exec_update :exec_delete
|
258
|
-
|
259
|
-
def last_inserted_id(result)
|
260
|
-
@connection.last_insert_row_id
|
261
|
-
end
|
262
|
-
|
263
|
-
def execute(sql, name = nil) #:nodoc:
|
264
|
-
if preventing_writes? && write_query?(sql)
|
265
|
-
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
266
|
-
end
|
267
|
-
|
268
|
-
materialize_transactions
|
269
|
-
|
270
|
-
log(sql, name) do
|
271
|
-
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
272
|
-
@connection.execute(sql)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
def begin_db_transaction #:nodoc:
|
278
|
-
log("begin transaction", nil) { @connection.transaction }
|
279
|
-
end
|
280
|
-
|
281
|
-
def commit_db_transaction #:nodoc:
|
282
|
-
log("commit transaction", nil) { @connection.commit }
|
283
|
-
end
|
284
|
-
|
285
|
-
def exec_rollback_db_transaction #:nodoc:
|
286
|
-
log("rollback transaction", nil) { @connection.rollback }
|
287
|
-
end
|
288
|
-
|
289
212
|
# SCHEMA STATEMENTS ========================================
|
290
213
|
|
291
214
|
def primary_keys(table_name) # :nodoc:
|
@@ -381,15 +304,26 @@ module ActiveRecord
|
|
381
304
|
end
|
382
305
|
end
|
383
306
|
|
384
|
-
def
|
385
|
-
|
386
|
-
transaction(requires_new: true) do
|
387
|
-
tables_to_delete.each { |table| delete "DELETE FROM #{quote_table_name(table)}", "Fixture Delete" }
|
307
|
+
def build_insert_sql(insert) # :nodoc:
|
308
|
+
sql = +"INSERT #{insert.into} #{insert.values_list}"
|
388
309
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
310
|
+
if insert.skip_duplicates?
|
311
|
+
sql << " ON CONFLICT #{insert.conflict_target} DO NOTHING"
|
312
|
+
elsif insert.update_duplicates?
|
313
|
+
sql << " ON CONFLICT #{insert.conflict_target} DO UPDATE SET "
|
314
|
+
sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",")
|
315
|
+
end
|
316
|
+
|
317
|
+
sql
|
318
|
+
end
|
319
|
+
|
320
|
+
def get_database_version # :nodoc:
|
321
|
+
SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
|
322
|
+
end
|
323
|
+
|
324
|
+
def check_version # :nodoc:
|
325
|
+
if database_version < "3.8.0"
|
326
|
+
raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.8."
|
393
327
|
end
|
394
328
|
end
|
395
329
|
|
@@ -400,12 +334,6 @@ module ActiveRecord
|
|
400
334
|
999
|
401
335
|
end
|
402
336
|
|
403
|
-
def check_version
|
404
|
-
if sqlite_version < "3.8.0"
|
405
|
-
raise "Your version of SQLite (#{sqlite_version}) is too old. Active Record supports SQLite >= 3.8."
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
337
|
def initialize_type_map(m = type_map)
|
410
338
|
super
|
411
339
|
register_class_with_limit m, %r(int)i, SQLite3Integer
|
@@ -523,10 +451,6 @@ module ActiveRecord
|
|
523
451
|
SELECT #{quoted_from_columns} FROM #{quote_table_name(from)}")
|
524
452
|
end
|
525
453
|
|
526
|
-
def sqlite_version
|
527
|
-
@sqlite_version ||= SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
|
528
|
-
end
|
529
|
-
|
530
454
|
def translate_exception(exception, message:, sql:, binds:)
|
531
455
|
case exception.message
|
532
456
|
# SQLite 3.8.2 returns a newly formatted error message:
|
@@ -589,7 +513,21 @@ module ActiveRecord
|
|
589
513
|
Arel::Visitors::SQLite.new(self)
|
590
514
|
end
|
591
515
|
|
516
|
+
def build_statement_pool
|
517
|
+
StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
|
518
|
+
end
|
519
|
+
|
520
|
+
def connect
|
521
|
+
@connection = ::SQLite3::Database.new(
|
522
|
+
@config[:database].to_s,
|
523
|
+
@config.merge(results_as_hash: true)
|
524
|
+
)
|
525
|
+
configure_connection
|
526
|
+
end
|
527
|
+
|
592
528
|
def configure_connection
|
529
|
+
@connection.busy_timeout(self.class.type_cast_config_to_integer(@config[:timeout])) if @config[:timeout]
|
530
|
+
|
593
531
|
execute("PRAGMA foreign_keys = ON", "SCHEMA")
|
594
532
|
end
|
595
533
|
|
@@ -85,14 +85,14 @@ module ActiveRecord
|
|
85
85
|
# based on the requested role:
|
86
86
|
#
|
87
87
|
# ActiveRecord::Base.connected_to(role: :writing) do
|
88
|
-
# Dog.create! # creates dog using dog connection
|
88
|
+
# Dog.create! # creates dog using dog writing connection
|
89
89
|
# end
|
90
90
|
#
|
91
91
|
# ActiveRecord::Base.connected_to(role: :reading) do
|
92
92
|
# Dog.create! # throws exception because we're on a replica
|
93
93
|
# end
|
94
94
|
#
|
95
|
-
# ActiveRecord::Base.connected_to(role: :
|
95
|
+
# ActiveRecord::Base.connected_to(role: :unknown_role) do
|
96
96
|
# # raises exception due to non-existent role
|
97
97
|
# end
|
98
98
|
#
|
@@ -100,11 +100,20 @@ module ActiveRecord
|
|
100
100
|
# you can use +connected_to+ with a +database+ argument. The +database+ argument
|
101
101
|
# expects a symbol that corresponds to the database key in your config.
|
102
102
|
#
|
103
|
-
# This will connect to a new database for the queries inside the block.
|
104
|
-
#
|
105
103
|
# ActiveRecord::Base.connected_to(database: :animals_slow_replica) do
|
106
104
|
# Dog.run_a_long_query # runs a long query while connected to the +animals_slow_replica+
|
107
105
|
# end
|
106
|
+
#
|
107
|
+
# This will connect to a new database for the queries inside the block. By
|
108
|
+
# default the `:writing` role will be used since all connections must be assigned
|
109
|
+
# a role. If you would like to use a different role you can pass a hash to database:
|
110
|
+
#
|
111
|
+
# ActiveRecord::Base.connected_to(database: { readonly_slow: :animals_slow_replica }) do
|
112
|
+
# # runs a long query while connected to the +animals_slow_replica+ using the readonly_slow role.
|
113
|
+
# Dog.run_a_long_query
|
114
|
+
# end
|
115
|
+
#
|
116
|
+
# When using the database key a new connection will be established every time.
|
108
117
|
def connected_to(database: nil, role: nil, &blk)
|
109
118
|
if database && role
|
110
119
|
raise ArgumentError, "connected_to can only accept a `database` or a `role` argument, but not both arguments."
|
@@ -112,17 +121,14 @@ module ActiveRecord
|
|
112
121
|
if database.is_a?(Hash)
|
113
122
|
role, database = database.first
|
114
123
|
role = role.to_sym
|
115
|
-
else
|
116
|
-
role = database.to_sym
|
117
124
|
end
|
118
125
|
|
119
126
|
config_hash = resolve_config_for_connection(database)
|
120
127
|
handler = lookup_connection_handler(role)
|
121
128
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
129
|
+
handler.establish_connection(config_hash)
|
130
|
+
|
131
|
+
with_handler(role, &blk)
|
126
132
|
elsif role
|
127
133
|
with_handler(role.to_sym, &blk)
|
128
134
|
else
|
@@ -154,6 +160,7 @@ module ActiveRecord
|
|
154
160
|
end
|
155
161
|
|
156
162
|
def lookup_connection_handler(handler_key) # :nodoc:
|
163
|
+
handler_key ||= ActiveRecord::Base.writing_role
|
157
164
|
connection_handlers[handler_key] ||= ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
158
165
|
end
|
159
166
|
|
data/lib/active_record/core.rb
CHANGED
@@ -101,7 +101,6 @@ module ActiveRecord
|
|
101
101
|
# environment where dumping schema is rarely needed.
|
102
102
|
mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
|
103
103
|
|
104
|
-
mattr_accessor :database_selector, instance_writer: false
|
105
104
|
##
|
106
105
|
# :singleton-method:
|
107
106
|
# Specifies which database schemas to dump when calling db:structure:dump.
|
@@ -161,7 +160,7 @@ module ActiveRecord
|
|
161
160
|
return super if block_given? ||
|
162
161
|
primary_key.nil? ||
|
163
162
|
scope_attributes? ||
|
164
|
-
columns_hash.
|
163
|
+
columns_hash.key?(inheritance_column) && !base_class?
|
165
164
|
|
166
165
|
id = ids.first
|
167
166
|
|
@@ -175,14 +174,14 @@ module ActiveRecord
|
|
175
174
|
|
176
175
|
record = statement.execute([id], connection)&.first
|
177
176
|
unless record
|
178
|
-
raise RecordNotFound.new("Couldn't find #{name} with '#{
|
179
|
-
name, primary_key, id)
|
177
|
+
raise RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id)
|
180
178
|
end
|
181
179
|
record
|
182
180
|
end
|
183
181
|
|
184
182
|
def find_by(*args) # :nodoc:
|
185
|
-
return super if scope_attributes? || reflect_on_all_aggregations.any?
|
183
|
+
return super if scope_attributes? || reflect_on_all_aggregations.any? ||
|
184
|
+
columns_hash.key?(inheritance_column) && !base_class?
|
186
185
|
|
187
186
|
hash = args.first
|
188
187
|
|
@@ -269,7 +268,8 @@ module ActiveRecord
|
|
269
268
|
end
|
270
269
|
|
271
270
|
def arel_attribute(name, table = arel_table) # :nodoc:
|
272
|
-
name =
|
271
|
+
name = name.to_s
|
272
|
+
name = attribute_aliases[name] || name
|
273
273
|
table[name]
|
274
274
|
end
|
275
275
|
|
@@ -317,7 +317,7 @@ module ActiveRecord
|
|
317
317
|
# # Instantiates a single new object
|
318
318
|
# User.new(first_name: 'Jamie')
|
319
319
|
def initialize(attributes = nil)
|
320
|
-
|
320
|
+
@new_record = true
|
321
321
|
@attributes = self.class._default_attributes.deep_dup
|
322
322
|
|
323
323
|
init_internals
|
@@ -354,12 +354,10 @@ module ActiveRecord
|
|
354
354
|
# +attributes+ should be an attributes object, and unlike the
|
355
355
|
# `initialize` method, no assignment calls are made per attribute.
|
356
356
|
def init_with_attributes(attributes, new_record = false) # :nodoc:
|
357
|
-
init_internals
|
358
|
-
|
359
357
|
@new_record = new_record
|
360
358
|
@attributes = attributes
|
361
359
|
|
362
|
-
|
360
|
+
init_internals
|
363
361
|
|
364
362
|
yield self if block_given?
|
365
363
|
|
@@ -398,13 +396,13 @@ module ActiveRecord
|
|
398
396
|
##
|
399
397
|
def initialize_dup(other) # :nodoc:
|
400
398
|
@attributes = @attributes.deep_dup
|
401
|
-
@attributes.reset(
|
399
|
+
@attributes.reset(@primary_key)
|
402
400
|
|
403
401
|
_run_initialize_callbacks
|
404
402
|
|
405
403
|
@new_record = true
|
406
404
|
@destroyed = false
|
407
|
-
@_start_transaction_state =
|
405
|
+
@_start_transaction_state = nil
|
408
406
|
@transaction_state = nil
|
409
407
|
|
410
408
|
super
|
@@ -465,6 +463,7 @@ module ActiveRecord
|
|
465
463
|
|
466
464
|
# Returns +true+ if the attributes hash has been frozen.
|
467
465
|
def frozen?
|
466
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
468
467
|
@attributes.frozen?
|
469
468
|
end
|
470
469
|
|
@@ -569,22 +568,18 @@ module ActiveRecord
|
|
569
568
|
end
|
570
569
|
|
571
570
|
def init_internals
|
571
|
+
@primary_key = self.class.primary_key
|
572
572
|
@readonly = false
|
573
573
|
@destroyed = false
|
574
574
|
@marked_for_destruction = false
|
575
575
|
@destroyed_by_association = nil
|
576
|
-
@
|
577
|
-
@_start_transaction_state = {}
|
576
|
+
@_start_transaction_state = nil
|
578
577
|
@transaction_state = nil
|
579
|
-
end
|
580
578
|
|
581
|
-
|
579
|
+
self.class.define_attribute_methods
|
582
580
|
end
|
583
581
|
|
584
|
-
def
|
585
|
-
if frozen?
|
586
|
-
@attributes = @attributes.dup
|
587
|
-
end
|
582
|
+
def initialize_internals_callback
|
588
583
|
end
|
589
584
|
|
590
585
|
def custom_inspect_method_defined?
|