activerecord 4.0.4 → 4.1.16
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1632 -1797
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/examples/performance.rb +30 -18
- data/examples/simple.rb +4 -4
- data/lib/active_record/aggregations.rb +2 -1
- data/lib/active_record/association_relation.rb +4 -0
- data/lib/active_record/associations/alias_tracker.rb +49 -29
- data/lib/active_record/associations/association.rb +9 -17
- data/lib/active_record/associations/association_scope.rb +59 -49
- data/lib/active_record/associations/belongs_to_association.rb +34 -25
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +6 -1
- data/lib/active_record/associations/builder/association.rb +84 -54
- data/lib/active_record/associations/builder/belongs_to.rb +90 -58
- data/lib/active_record/associations/builder/collection_association.rb +47 -45
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +119 -25
- data/lib/active_record/associations/builder/has_many.rb +3 -3
- data/lib/active_record/associations/builder/has_one.rb +5 -7
- data/lib/active_record/associations/builder/singular_association.rb +6 -7
- data/lib/active_record/associations/collection_association.rb +121 -111
- data/lib/active_record/associations/collection_proxy.rb +73 -18
- data/lib/active_record/associations/has_many_association.rb +14 -11
- data/lib/active_record/associations/has_many_through_association.rb +33 -6
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +46 -104
- data/lib/active_record/associations/join_dependency/join_base.rb +6 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +18 -37
- data/lib/active_record/associations/join_dependency.rb +208 -168
- data/lib/active_record/associations/preloader/association.rb +69 -27
- data/lib/active_record/associations/preloader/collection_association.rb +2 -2
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/singular_association.rb +3 -3
- data/lib/active_record/associations/preloader/through_association.rb +58 -26
- data/lib/active_record/associations/preloader.rb +63 -49
- data/lib/active_record/associations/singular_association.rb +6 -5
- data/lib/active_record/associations/through_association.rb +30 -9
- data/lib/active_record/associations.rb +116 -42
- data/lib/active_record/attribute_assignment.rb +6 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -1
- data/lib/active_record/attribute_methods/dirty.rb +35 -26
- data/lib/active_record/attribute_methods/primary_key.rb +8 -1
- data/lib/active_record/attribute_methods/read.rb +56 -29
- data/lib/active_record/attribute_methods/serialization.rb +44 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +13 -1
- data/lib/active_record/attribute_methods/write.rb +59 -26
- data/lib/active_record/attribute_methods.rb +82 -43
- data/lib/active_record/autosave_association.rb +209 -194
- data/lib/active_record/base.rb +6 -2
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/json.rb +13 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +5 -10
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +14 -24
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -13
- data/lib/active_record/connection_adapters/abstract/quoting.rb +6 -3
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +90 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -8
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +45 -70
- data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +28 -96
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +74 -66
- data/lib/active_record/connection_adapters/column.rb +1 -35
- data/lib/active_record/connection_adapters/connection_specification.rb +231 -43
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +10 -5
- data/lib/active_record/connection_adapters/mysql_adapter.rb +24 -17
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +22 -15
- data/lib/active_record/connection_adapters/postgresql/cast.rb +12 -4
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -44
- data/lib/active_record/connection_adapters/postgresql/oid.rb +38 -14
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +37 -12
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +20 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +98 -52
- data/lib/active_record/connection_adapters/schema_cache.rb +8 -29
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +55 -60
- data/lib/active_record/connection_handling.rb +39 -5
- data/lib/active_record/core.rb +38 -54
- data/lib/active_record/counter_cache.rb +9 -10
- data/lib/active_record/dynamic_matchers.rb +6 -2
- data/lib/active_record/enum.rb +199 -0
- data/lib/active_record/errors.rb +22 -5
- data/lib/active_record/fixture_set/file.rb +2 -1
- data/lib/active_record/fixtures.rb +173 -76
- data/lib/active_record/gem_version.rb +15 -0
- data/lib/active_record/inheritance.rb +23 -9
- data/lib/active_record/integration.rb +54 -1
- data/lib/active_record/locking/optimistic.rb +7 -2
- data/lib/active_record/locking/pessimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +6 -13
- data/lib/active_record/migration/command_recorder.rb +8 -2
- data/lib/active_record/migration.rb +91 -56
- data/lib/active_record/model_schema.rb +7 -14
- data/lib/active_record/nested_attributes.rb +25 -13
- data/lib/active_record/no_touching.rb +52 -0
- data/lib/active_record/null_relation.rb +26 -6
- data/lib/active_record/persistence.rb +23 -29
- data/lib/active_record/querying.rb +15 -12
- data/lib/active_record/railtie.rb +12 -61
- data/lib/active_record/railties/databases.rake +37 -56
- data/lib/active_record/readonly_attributes.rb +0 -6
- data/lib/active_record/reflection.rb +230 -79
- data/lib/active_record/relation/batches.rb +74 -24
- data/lib/active_record/relation/calculations.rb +52 -48
- data/lib/active_record/relation/delegation.rb +54 -39
- data/lib/active_record/relation/finder_methods.rb +210 -67
- data/lib/active_record/relation/merger.rb +15 -12
- data/lib/active_record/relation/predicate_builder/array_handler.rb +29 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder.rb +81 -40
- data/lib/active_record/relation/query_methods.rb +185 -108
- data/lib/active_record/relation/spawn_methods.rb +8 -5
- data/lib/active_record/relation.rb +79 -84
- data/lib/active_record/result.rb +45 -6
- data/lib/active_record/runtime_registry.rb +5 -0
- data/lib/active_record/sanitization.rb +4 -4
- data/lib/active_record/schema_dumper.rb +18 -6
- data/lib/active_record/schema_migration.rb +31 -18
- data/lib/active_record/scoping/default.rb +5 -18
- data/lib/active_record/scoping/named.rb +14 -29
- data/lib/active_record/scoping.rb +5 -0
- data/lib/active_record/store.rb +67 -18
- data/lib/active_record/tasks/database_tasks.rb +66 -26
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -10
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
- data/lib/active_record/timestamp.rb +6 -6
- data/lib/active_record/transactions.rb +10 -12
- data/lib/active_record/validations/presence.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +19 -9
- data/lib/active_record/version.rb +4 -7
- data/lib/active_record.rb +5 -7
- data/lib/rails/generators/active_record/migration/migration_generator.rb +4 -0
- data/lib/rails/generators/active_record/migration.rb +18 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +4 -0
- data/lib/rails/generators/active_record.rb +2 -8
- metadata +18 -30
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -65
- data/lib/active_record/associations/join_helper.rb +0 -45
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
- data/lib/active_record/tasks/firebird_database_tasks.rb +0 -56
- data/lib/active_record/tasks/oracle_database_tasks.rb +0 -45
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +0 -48
- data/lib/active_record/test_case.rb +0 -96
@@ -31,6 +31,12 @@ module ActiveRecord
|
|
31
31
|
db.busy_timeout(ConnectionAdapters::SQLite3Adapter.type_cast_config_to_integer(config[:timeout])) if config[:timeout]
|
32
32
|
|
33
33
|
ConnectionAdapters::SQLite3Adapter.new(db, logger, config)
|
34
|
+
rescue Errno::ENOENT => error
|
35
|
+
if error.message.include?("No such file or directory")
|
36
|
+
raise ActiveRecord::NoDatabaseError.new(error.message)
|
37
|
+
else
|
38
|
+
raise error
|
39
|
+
end
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
@@ -53,6 +59,23 @@ module ActiveRecord
|
|
53
59
|
#
|
54
60
|
# * <tt>:database</tt> - Path to the database file.
|
55
61
|
class SQLite3Adapter < AbstractAdapter
|
62
|
+
include Savepoints
|
63
|
+
|
64
|
+
NATIVE_DATABASE_TYPES = {
|
65
|
+
primary_key: 'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL',
|
66
|
+
string: { name: "varchar", limit: 255 },
|
67
|
+
text: { name: "text" },
|
68
|
+
integer: { name: "integer" },
|
69
|
+
float: { name: "float" },
|
70
|
+
decimal: { name: "decimal" },
|
71
|
+
datetime: { name: "datetime" },
|
72
|
+
timestamp: { name: "datetime" },
|
73
|
+
time: { name: "time" },
|
74
|
+
date: { name: "date" },
|
75
|
+
binary: { name: "blob" },
|
76
|
+
boolean: { name: "boolean" }
|
77
|
+
}
|
78
|
+
|
56
79
|
class Version
|
57
80
|
include Comparable
|
58
81
|
|
@@ -124,14 +147,16 @@ module ActiveRecord
|
|
124
147
|
'SQLite'
|
125
148
|
end
|
126
149
|
|
127
|
-
# Returns true
|
128
150
|
def supports_ddl_transactions?
|
129
151
|
true
|
130
152
|
end
|
131
153
|
|
132
|
-
# Returns true if SQLite version is '3.6.8' or greater, false otherwise.
|
133
154
|
def supports_savepoints?
|
134
|
-
|
155
|
+
true
|
156
|
+
end
|
157
|
+
|
158
|
+
def supports_partial_index?
|
159
|
+
sqlite_version >= '3.8.0'
|
135
160
|
end
|
136
161
|
|
137
162
|
# Returns true, since this connection adapter supports prepared statement
|
@@ -145,7 +170,6 @@ module ActiveRecord
|
|
145
170
|
true
|
146
171
|
end
|
147
172
|
|
148
|
-
# Returns true.
|
149
173
|
def supports_primary_key? #:nodoc:
|
150
174
|
true
|
151
175
|
end
|
@@ -154,7 +178,6 @@ module ActiveRecord
|
|
154
178
|
true
|
155
179
|
end
|
156
180
|
|
157
|
-
# Returns true
|
158
181
|
def supports_add_column?
|
159
182
|
true
|
160
183
|
end
|
@@ -176,16 +199,6 @@ module ActiveRecord
|
|
176
199
|
@statements.clear
|
177
200
|
end
|
178
201
|
|
179
|
-
# Returns true
|
180
|
-
def supports_count_distinct? #:nodoc:
|
181
|
-
true
|
182
|
-
end
|
183
|
-
|
184
|
-
# Returns true
|
185
|
-
def supports_autoincrement? #:nodoc:
|
186
|
-
true
|
187
|
-
end
|
188
|
-
|
189
202
|
def supports_index_sort_order?
|
190
203
|
true
|
191
204
|
end
|
@@ -198,20 +211,7 @@ module ActiveRecord
|
|
198
211
|
end
|
199
212
|
|
200
213
|
def native_database_types #:nodoc:
|
201
|
-
|
202
|
-
:primary_key => default_primary_key_type,
|
203
|
-
:string => { :name => "varchar", :limit => 255 },
|
204
|
-
:text => { :name => "text" },
|
205
|
-
:integer => { :name => "integer" },
|
206
|
-
:float => { :name => "float" },
|
207
|
-
:decimal => { :name => "decimal" },
|
208
|
-
:datetime => { :name => "datetime" },
|
209
|
-
:timestamp => { :name => "datetime" },
|
210
|
-
:time => { :name => "time" },
|
211
|
-
:date => { :name => "date" },
|
212
|
-
:binary => { :name => "blob" },
|
213
|
-
:boolean => { :name => "boolean" }
|
214
|
-
}
|
214
|
+
NATIVE_DATABASE_TYPES
|
215
215
|
end
|
216
216
|
|
217
217
|
# Returns the current database encoding format as a string, eg: 'UTF-8'
|
@@ -219,7 +219,6 @@ module ActiveRecord
|
|
219
219
|
@connection.encoding.to_s
|
220
220
|
end
|
221
221
|
|
222
|
-
# Returns true.
|
223
222
|
def supports_explain?
|
224
223
|
true
|
225
224
|
end
|
@@ -227,8 +226,8 @@ module ActiveRecord
|
|
227
226
|
# QUOTING ==================================================
|
228
227
|
|
229
228
|
def quote(value, column = nil)
|
230
|
-
if value.kind_of?(String) && column && column.type == :binary
|
231
|
-
s =
|
229
|
+
if value.kind_of?(String) && column && column.type == :binary
|
230
|
+
s = value.unpack("H*")[0]
|
232
231
|
"x'#{s}'"
|
233
232
|
else
|
234
233
|
super
|
@@ -292,14 +291,20 @@ module ActiveRecord
|
|
292
291
|
end
|
293
292
|
|
294
293
|
def exec_query(sql, name = nil, binds = [])
|
295
|
-
|
294
|
+
type_casted_binds = binds.map { |col, val|
|
295
|
+
[col, type_cast(val, col)]
|
296
|
+
}
|
296
297
|
|
298
|
+
log(sql, name, type_casted_binds) do
|
297
299
|
# Don't cache statements if they are not prepared
|
298
300
|
if without_prepared_statement?(binds)
|
299
301
|
stmt = @connection.prepare(sql)
|
300
|
-
|
301
|
-
|
302
|
-
|
302
|
+
begin
|
303
|
+
cols = stmt.columns
|
304
|
+
records = stmt.to_a
|
305
|
+
ensure
|
306
|
+
stmt.close
|
307
|
+
end
|
303
308
|
stmt = records
|
304
309
|
else
|
305
310
|
cache = @statements[sql] ||= {
|
@@ -308,9 +313,7 @@ module ActiveRecord
|
|
308
313
|
stmt = cache[:stmt]
|
309
314
|
cols = cache[:cols] ||= stmt.columns
|
310
315
|
stmt.reset!
|
311
|
-
stmt.bind_params
|
312
|
-
type_cast(val, col)
|
313
|
-
}
|
316
|
+
stmt.bind_params type_casted_binds.map { |_, val| val }
|
314
317
|
end
|
315
318
|
|
316
319
|
ActiveRecord::Result.new(cols, stmt.to_a)
|
@@ -351,18 +354,6 @@ module ActiveRecord
|
|
351
354
|
exec_query(sql, name, binds).rows
|
352
355
|
end
|
353
356
|
|
354
|
-
def create_savepoint
|
355
|
-
execute("SAVEPOINT #{current_savepoint_name}")
|
356
|
-
end
|
357
|
-
|
358
|
-
def rollback_to_savepoint
|
359
|
-
execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
|
360
|
-
end
|
361
|
-
|
362
|
-
def release_savepoint
|
363
|
-
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
|
364
|
-
end
|
365
|
-
|
366
357
|
def begin_db_transaction #:nodoc:
|
367
358
|
log('begin transaction',nil) { @connection.transaction }
|
368
359
|
end
|
@@ -413,13 +404,25 @@ module ActiveRecord
|
|
413
404
|
# Returns an array of indexes for the given table.
|
414
405
|
def indexes(table_name, name = nil) #:nodoc:
|
415
406
|
exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", 'SCHEMA').map do |row|
|
407
|
+
sql = <<-SQL
|
408
|
+
SELECT sql
|
409
|
+
FROM sqlite_master
|
410
|
+
WHERE name=#{quote(row['name'])} AND type='index'
|
411
|
+
UNION ALL
|
412
|
+
SELECT sql
|
413
|
+
FROM sqlite_temp_master
|
414
|
+
WHERE name=#{quote(row['name'])} AND type='index'
|
415
|
+
SQL
|
416
|
+
index_sql = exec_query(sql).first['sql']
|
417
|
+
match = /\sWHERE\s+(.+)$/i.match(index_sql)
|
418
|
+
where = match[1] if match
|
416
419
|
IndexDefinition.new(
|
417
420
|
table_name,
|
418
421
|
row['name'],
|
419
422
|
row['unique'] != 0,
|
420
423
|
exec_query("PRAGMA index_info('#{row['name']}')", "SCHEMA").map { |col|
|
421
424
|
col['name']
|
422
|
-
})
|
425
|
+
}, nil, nil, where)
|
423
426
|
end
|
424
427
|
end
|
425
428
|
|
@@ -606,14 +609,6 @@ module ActiveRecord
|
|
606
609
|
@sqlite_version ||= SQLite3Adapter::Version.new(select_value('select sqlite_version(*)'))
|
607
610
|
end
|
608
611
|
|
609
|
-
def default_primary_key_type
|
610
|
-
if supports_autoincrement?
|
611
|
-
'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
|
612
|
-
else
|
613
|
-
'INTEGER PRIMARY KEY NOT NULL'
|
614
|
-
end
|
615
|
-
end
|
616
|
-
|
617
612
|
def translate_exception(exception, message)
|
618
613
|
case exception.message
|
619
614
|
# SQLite 3.8.2 returns a newly formatted error message:
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionHandling
|
3
|
+
RAILS_ENV = -> { (Rails.env if defined?(Rails)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] }
|
4
|
+
DEFAULT_ENV = -> { RAILS_ENV.call || "default_env" }
|
5
|
+
|
3
6
|
# Establishes the connection to the database. Accepts a hash as input where
|
4
7
|
# the <tt>:adapter</tt> key must be specified with the name of a database adapter (in lower-case)
|
5
8
|
# example for regular databases (MySQL, Postgresql, etc):
|
@@ -15,14 +18,14 @@ module ActiveRecord
|
|
15
18
|
# Example for SQLite database:
|
16
19
|
#
|
17
20
|
# ActiveRecord::Base.establish_connection(
|
18
|
-
# adapter: "
|
21
|
+
# adapter: "sqlite3",
|
19
22
|
# database: "path/to/dbfile"
|
20
23
|
# )
|
21
24
|
#
|
22
25
|
# Also accepts keys as strings (for parsing from YAML for example):
|
23
26
|
#
|
24
27
|
# ActiveRecord::Base.establish_connection(
|
25
|
-
# "adapter" => "
|
28
|
+
# "adapter" => "sqlite3",
|
26
29
|
# "database" => "path/to/dbfile"
|
27
30
|
# )
|
28
31
|
#
|
@@ -32,11 +35,19 @@ module ActiveRecord
|
|
32
35
|
# "postgres://myuser:mypass@localhost/somedatabase"
|
33
36
|
# )
|
34
37
|
#
|
38
|
+
# In case <tt>ActiveRecord::Base.configurations</tt> is set (Rails
|
39
|
+
# automatically loads the contents of config/database.yml into it),
|
40
|
+
# a symbol can also be given as argument, representing a key in the
|
41
|
+
# configuration hash:
|
42
|
+
#
|
43
|
+
# ActiveRecord::Base.establish_connection(:production)
|
44
|
+
#
|
35
45
|
# The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError
|
36
46
|
# may be returned on an error.
|
37
|
-
def establish_connection(spec =
|
38
|
-
|
39
|
-
|
47
|
+
def establish_connection(spec = nil)
|
48
|
+
spec ||= DEFAULT_ENV.call.to_sym
|
49
|
+
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new configurations
|
50
|
+
spec = resolver.spec(spec)
|
40
51
|
|
41
52
|
unless respond_to?(spec.adapter_method)
|
42
53
|
raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
|
@@ -46,6 +57,29 @@ module ActiveRecord
|
|
46
57
|
connection_handler.establish_connection self, spec
|
47
58
|
end
|
48
59
|
|
60
|
+
class MergeAndResolveDefaultUrlConfig # :nodoc:
|
61
|
+
def initialize(raw_configurations)
|
62
|
+
@raw_config = raw_configurations.dup
|
63
|
+
@env = DEFAULT_ENV.call.to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns fully resolved connection hashes.
|
67
|
+
# Merges connection information from `ENV['DATABASE_URL']` if available.
|
68
|
+
def resolve
|
69
|
+
ConnectionAdapters::ConnectionSpecification::Resolver.new(config).resolve_all
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def config
|
74
|
+
@raw_config.dup.tap do |cfg|
|
75
|
+
if url = ENV['DATABASE_URL']
|
76
|
+
cfg[@env] ||= {}
|
77
|
+
cfg[@env]["url"] ||= url
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
49
83
|
# Returns the connection currently associated with the class. This can
|
50
84
|
# also be used to "borrow" the connection to do database work unrelated
|
51
85
|
# to any of the specific Active Records.
|
data/lib/active_record/core.rb
CHANGED
@@ -42,9 +42,16 @@ module ActiveRecord
|
|
42
42
|
# 'database' => 'db/production.sqlite3'
|
43
43
|
# }
|
44
44
|
# }
|
45
|
-
|
45
|
+
def self.configurations=(config)
|
46
|
+
@@configurations = ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(config).resolve
|
47
|
+
end
|
46
48
|
self.configurations = {}
|
47
49
|
|
50
|
+
# Returns fully resolved configurations hash
|
51
|
+
def self.configurations
|
52
|
+
@@configurations
|
53
|
+
end
|
54
|
+
|
48
55
|
##
|
49
56
|
# :singleton-method:
|
50
57
|
# Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
|
@@ -71,11 +78,19 @@ module ActiveRecord
|
|
71
78
|
|
72
79
|
##
|
73
80
|
# :singleton-method:
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
|
78
|
-
|
81
|
+
# Specify whether schema dump should happen at the end of the
|
82
|
+
# db:migrate rake task. This is true by default, which is useful for the
|
83
|
+
# development environment. This should ideally be false in the production
|
84
|
+
# environment where dumping schema is rarely needed.
|
85
|
+
mattr_accessor :dump_schema_after_migration, instance_writer: false
|
86
|
+
self.dump_schema_after_migration = true
|
87
|
+
|
88
|
+
mattr_accessor :maintain_test_schema, instance_accessor: false
|
89
|
+
|
90
|
+
def self.disable_implicit_join_references=(value)
|
91
|
+
ActiveSupport::Deprecation.warn("Implicit join references were removed with Rails 4.1." \
|
92
|
+
"Make sure to remove this configuration because it does nothing.")
|
93
|
+
end
|
79
94
|
|
80
95
|
class_attribute :default_connection_handler, instance_writer: false
|
81
96
|
|
@@ -92,14 +107,12 @@ module ActiveRecord
|
|
92
107
|
|
93
108
|
module ClassMethods
|
94
109
|
def initialize_generated_modules
|
95
|
-
|
96
|
-
|
97
|
-
generated_feature_methods
|
110
|
+
generated_association_methods
|
98
111
|
end
|
99
112
|
|
100
|
-
def
|
101
|
-
@
|
102
|
-
mod = const_set(:
|
113
|
+
def generated_association_methods
|
114
|
+
@generated_association_methods ||= begin
|
115
|
+
mod = const_set(:GeneratedAssociationMethods, Module.new)
|
103
116
|
include mod
|
104
117
|
mod
|
105
118
|
end
|
@@ -131,25 +144,24 @@ module ActiveRecord
|
|
131
144
|
# class Post < ActiveRecord::Base
|
132
145
|
# scope :published_and_commented, -> { published.and(self.arel_table[:comments_count].gt(0)) }
|
133
146
|
# end
|
134
|
-
def arel_table
|
147
|
+
def arel_table # :nodoc:
|
135
148
|
@arel_table ||= Arel::Table.new(table_name, arel_engine)
|
136
149
|
end
|
137
150
|
|
138
151
|
# Returns the Arel engine.
|
139
|
-
def arel_engine
|
140
|
-
@arel_engine ||=
|
152
|
+
def arel_engine # :nodoc:
|
153
|
+
@arel_engine ||=
|
141
154
|
if Base == self || connection_handler.retrieve_connection_pool(self)
|
142
155
|
self
|
143
156
|
else
|
144
157
|
superclass.arel_engine
|
145
158
|
end
|
146
|
-
end
|
147
159
|
end
|
148
160
|
|
149
161
|
private
|
150
162
|
|
151
163
|
def relation #:nodoc:
|
152
|
-
relation = Relation.
|
164
|
+
relation = Relation.create(self, arel_table)
|
153
165
|
|
154
166
|
if finder_needs_type_condition?
|
155
167
|
relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
|
@@ -176,9 +188,7 @@ module ActiveRecord
|
|
176
188
|
@column_types = self.class.column_types
|
177
189
|
|
178
190
|
init_internals
|
179
|
-
|
180
|
-
ensure_proper_type
|
181
|
-
populate_with_current_scope_attributes
|
191
|
+
initialize_internals_callback
|
182
192
|
|
183
193
|
# +options+ argument is only needed to make protected_attributes gem easier to hook.
|
184
194
|
# Remove it when we drop support to this gem.
|
@@ -207,6 +217,8 @@ module ActiveRecord
|
|
207
217
|
|
208
218
|
@new_record = false
|
209
219
|
|
220
|
+
self.class.define_attribute_methods
|
221
|
+
|
210
222
|
run_callbacks :find
|
211
223
|
run_callbacks :initialize
|
212
224
|
|
@@ -249,16 +261,13 @@ module ActiveRecord
|
|
249
261
|
|
250
262
|
run_callbacks(:initialize) unless _initialize_callbacks.empty?
|
251
263
|
|
252
|
-
@changed_attributes = {}
|
253
|
-
init_changed_attributes
|
254
|
-
|
255
264
|
@aggregation_cache = {}
|
256
265
|
@association_cache = {}
|
257
266
|
@attributes_cache = {}
|
258
267
|
|
259
268
|
@new_record = true
|
269
|
+
@destroyed = false
|
260
270
|
|
261
|
-
ensure_proper_type
|
262
271
|
super
|
263
272
|
end
|
264
273
|
|
@@ -290,7 +299,7 @@ module ActiveRecord
|
|
290
299
|
def ==(comparison_object)
|
291
300
|
super ||
|
292
301
|
comparison_object.instance_of?(self.class) &&
|
293
|
-
id.
|
302
|
+
!id.nil? &&
|
294
303
|
comparison_object.id == id
|
295
304
|
end
|
296
305
|
alias :eql? :==
|
@@ -318,6 +327,8 @@ module ActiveRecord
|
|
318
327
|
def <=>(other_object)
|
319
328
|
if other_object.is_a?(self.class)
|
320
329
|
self.to_key <=> other_object.to_key
|
330
|
+
else
|
331
|
+
super
|
321
332
|
end
|
322
333
|
end
|
323
334
|
|
@@ -332,14 +343,6 @@ module ActiveRecord
|
|
332
343
|
@readonly = true
|
333
344
|
end
|
334
345
|
|
335
|
-
# Returns the connection currently associated with the class. This can
|
336
|
-
# also be used to "borrow" the connection to do database work that isn't
|
337
|
-
# easily done without going straight to SQL.
|
338
|
-
def connection
|
339
|
-
ActiveSupport::Deprecation.warn("#connection is deprecated in favour of accessing it via the class")
|
340
|
-
self.class.connection
|
341
|
-
end
|
342
|
-
|
343
346
|
def connection_handler
|
344
347
|
self.class.connection_handler
|
345
348
|
end
|
@@ -362,7 +365,7 @@ module ActiveRecord
|
|
362
365
|
|
363
366
|
# Returns a hash of the given methods with their names as keys and returned values as values.
|
364
367
|
def slice(*methods)
|
365
|
-
Hash[methods.map { |method| [method, public_send(method)] }].with_indifferent_access
|
368
|
+
Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
|
366
369
|
end
|
367
370
|
|
368
371
|
def set_transaction_state(state) # :nodoc:
|
@@ -373,17 +376,6 @@ module ActiveRecord
|
|
373
376
|
!_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_create_callbacks.empty?
|
374
377
|
end
|
375
378
|
|
376
|
-
# Required to deserialize Syck properly.
|
377
|
-
if YAML.const_defined?(:ENGINE) && YAML::ENGINE.syck?
|
378
|
-
ActiveSupport::Deprecation.warn(
|
379
|
-
"Syck is deprecated and support for serialization has been removed." \
|
380
|
-
" ActiveRecord::Core#yaml_initialize will be removed in 4.1 which will break deserialization support with Syck."
|
381
|
-
)
|
382
|
-
def yaml_initialize(tag, coder) # :nodoc:
|
383
|
-
init_with(coder)
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
379
|
private
|
388
380
|
|
389
381
|
# Updates the attributes on this particular ActiveRecord object so that
|
@@ -440,8 +432,6 @@ module ActiveRecord
|
|
440
432
|
@aggregation_cache = {}
|
441
433
|
@association_cache = {}
|
442
434
|
@attributes_cache = {}
|
443
|
-
@previously_changed = {}
|
444
|
-
@changed_attributes = {}
|
445
435
|
@readonly = false
|
446
436
|
@destroyed = false
|
447
437
|
@marked_for_destruction = false
|
@@ -453,13 +443,7 @@ module ActiveRecord
|
|
453
443
|
@reflects_state = [false]
|
454
444
|
end
|
455
445
|
|
456
|
-
def
|
457
|
-
# Intentionally avoid using #column_defaults since overridden defaults (as is done in
|
458
|
-
# optimistic locking) won't get written unless they get marked as changed
|
459
|
-
self.class.columns.each do |c|
|
460
|
-
attr, orig_value = c.name, c.default
|
461
|
-
@changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @attributes[attr])
|
462
|
-
end
|
446
|
+
def initialize_internals_callback
|
463
447
|
end
|
464
448
|
|
465
449
|
# This method is needed to make protected_attributes gem easier to hook.
|
@@ -20,7 +20,7 @@ module ActiveRecord
|
|
20
20
|
def reset_counters(id, *counters)
|
21
21
|
object = find(id)
|
22
22
|
counters.each do |association|
|
23
|
-
has_many_association =
|
23
|
+
has_many_association = _reflect_on_association(association.to_sym)
|
24
24
|
raise ArgumentError, "'#{self.name}' has no association called '#{association}'" unless has_many_association
|
25
25
|
|
26
26
|
if has_many_association.is_a? ActiveRecord::Reflection::ThroughReflection
|
@@ -29,13 +29,12 @@ module ActiveRecord
|
|
29
29
|
|
30
30
|
foreign_key = has_many_association.foreign_key.to_s
|
31
31
|
child_class = has_many_association.klass
|
32
|
-
|
33
|
-
reflection = belongs_to.find { |e| e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
|
32
|
+
reflection = child_class._reflections.values.find { |e| :belongs_to == e.macro && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
|
34
33
|
counter_name = reflection.counter_cache_column
|
35
34
|
|
36
35
|
stmt = unscoped.where(arel_table[primary_key].eq(object.id)).arel.compile_update({
|
37
|
-
arel_table[counter_name] => object.send(association).count
|
38
|
-
})
|
36
|
+
arel_table[counter_name] => object.send(association).count(:all)
|
37
|
+
}, primary_key)
|
39
38
|
connection.update stmt
|
40
39
|
end
|
41
40
|
return true
|
@@ -50,7 +49,7 @@ module ActiveRecord
|
|
50
49
|
# ==== Parameters
|
51
50
|
#
|
52
51
|
# * +id+ - The id of the object you wish to update a counter on or an Array of ids.
|
53
|
-
# * +counters+ -
|
52
|
+
# * +counters+ - A Hash containing the names of the fields
|
54
53
|
# to update as keys and the amount to update the field by as values.
|
55
54
|
#
|
56
55
|
# ==== Examples
|
@@ -82,10 +81,10 @@ module ActiveRecord
|
|
82
81
|
|
83
82
|
# Increment a numeric field by one, via a direct SQL update.
|
84
83
|
#
|
85
|
-
# This method is used primarily for maintaining counter_cache columns
|
86
|
-
# store aggregate values. For example, a DiscussionBoard may cache
|
87
|
-
# and comments_count to avoid running an SQL query to calculate the
|
88
|
-
# posts and comments there are each time it is displayed.
|
84
|
+
# This method is used primarily for maintaining counter_cache columns that are
|
85
|
+
# used to store aggregate values. For example, a DiscussionBoard may cache
|
86
|
+
# posts_count and comments_count to avoid running an SQL query to calculate the
|
87
|
+
# number of posts and comments there are, each time it is displayed.
|
89
88
|
#
|
90
89
|
# ==== Parameters
|
91
90
|
#
|
@@ -6,8 +6,12 @@ module ActiveRecord
|
|
6
6
|
# then we can remove the indirection.
|
7
7
|
|
8
8
|
def respond_to?(name, include_private = false)
|
9
|
-
|
10
|
-
|
9
|
+
if self == Base
|
10
|
+
super
|
11
|
+
else
|
12
|
+
match = Method.match(self, name)
|
13
|
+
match && match.valid? || super
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
private
|