activerecord 4.0.0.beta1 → 4.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 +573 -30
- data/README.rdoc +3 -3
- data/lib/active_record.rb +8 -2
- data/lib/active_record/associations.rb +16 -9
- data/lib/active_record/associations/association.rb +8 -6
- data/lib/active_record/associations/association_scope.rb +2 -1
- data/lib/active_record/associations/belongs_to_association.rb +2 -2
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/belongs_to.rb +37 -5
- data/lib/active_record/associations/collection_association.rb +38 -14
- data/lib/active_record/associations/collection_proxy.rb +18 -15
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +3 -3
- data/lib/active_record/associations/has_many_association.rb +4 -3
- data/lib/active_record/associations/has_many_through_association.rb +1 -1
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +29 -8
- data/lib/active_record/associations/join_dependency/join_association.rb +26 -6
- data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_part.rb +6 -6
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +1 -1
- data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +5 -5
- data/lib/active_record/attribute_methods.rb +20 -5
- data/lib/active_record/attribute_methods/dirty.rb +5 -1
- data/lib/active_record/attribute_methods/primary_key.rb +1 -1
- data/lib/active_record/attribute_methods/serialization.rb +9 -2
- data/lib/active_record/autosave_association.rb +19 -5
- data/lib/active_record/base.rb +3 -3
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +8 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +3 -9
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +2 -8
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +60 -61
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +13 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +291 -153
- data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +92 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +55 -29
- data/lib/active_record/connection_adapters/column.rb +4 -4
- data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -3
- data/lib/active_record/connection_adapters/mysql_adapter.rb +5 -5
- data/lib/active_record/connection_adapters/postgresql/cast.rb +22 -2
- data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -6
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +26 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +50 -9
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +53 -24
- data/lib/active_record/connection_adapters/schema_cache.rb +35 -7
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +13 -5
- data/lib/active_record/connection_handling.rb +7 -7
- data/lib/active_record/core.rb +43 -8
- data/lib/active_record/counter_cache.rb +2 -1
- data/lib/active_record/errors.rb +11 -10
- data/lib/active_record/explain.rb +9 -7
- data/lib/active_record/explain_registry.rb +30 -0
- data/lib/active_record/explain_subscriber.rb +3 -2
- data/lib/active_record/fixture_set/file.rb +1 -2
- data/lib/active_record/fixtures.rb +13 -7
- data/lib/active_record/inheritance.rb +12 -4
- data/lib/active_record/integration.rb +3 -3
- data/lib/active_record/locking/optimistic.rb +2 -2
- data/lib/active_record/log_subscriber.rb +2 -2
- data/lib/active_record/migration.rb +69 -21
- data/lib/active_record/model_schema.rb +1 -1
- data/lib/active_record/nested_attributes.rb +98 -46
- data/lib/active_record/persistence.rb +3 -3
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +18 -4
- data/lib/active_record/railties/console_sandbox.rb +3 -2
- data/lib/active_record/railties/controller_runtime.rb +2 -1
- data/lib/active_record/railties/databases.rake +38 -80
- data/lib/active_record/reflection.rb +36 -3
- data/lib/active_record/relation.rb +18 -8
- data/lib/active_record/relation/calculations.rb +10 -5
- data/lib/active_record/relation/delegation.rb +3 -5
- data/lib/active_record/relation/finder_methods.rb +27 -14
- data/lib/active_record/relation/merger.rb +30 -2
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_methods.rb +113 -16
- data/lib/active_record/runtime_registry.rb +17 -0
- data/lib/active_record/schema_dumper.rb +5 -1
- data/lib/active_record/schema_migration.rb +8 -5
- data/lib/active_record/scoping.rb +56 -2
- data/lib/active_record/scoping/default.rb +12 -11
- data/lib/active_record/scoping/named.rb +7 -3
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/statement_cache.rb +26 -0
- data/lib/active_record/tasks/database_tasks.rb +55 -10
- data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +7 -2
- data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
- data/lib/active_record/timestamp.rb +6 -0
- data/lib/active_record/transactions.rb +7 -3
- data/lib/active_record/validations.rb +1 -2
- data/lib/active_record/validations/uniqueness.rb +7 -3
- data/lib/active_record/version.rb +7 -6
- data/lib/rails/generators/active_record/migration/migration_generator.rb +9 -2
- data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb +4 -1
- metadata +17 -12
- data/examples/associations.png +0 -0
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'active_support/deprecation/reporting'
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
class SchemaCache
|
4
|
-
attr_reader :
|
6
|
+
attr_reader :version
|
5
7
|
attr_accessor :connection
|
6
8
|
|
7
9
|
def initialize(conn)
|
@@ -14,6 +16,15 @@ module ActiveRecord
|
|
14
16
|
prepare_default_proc
|
15
17
|
end
|
16
18
|
|
19
|
+
def primary_keys(table_name = nil)
|
20
|
+
if table_name
|
21
|
+
@primary_keys[table_name]
|
22
|
+
else
|
23
|
+
ActiveSupport::Deprecation.warn('call primary_keys with a table name!')
|
24
|
+
@primary_keys.dup
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
17
28
|
# A cached lookup for table existence.
|
18
29
|
def table_exists?(name)
|
19
30
|
return @tables[name] if @tables.key? name
|
@@ -30,12 +41,22 @@ module ActiveRecord
|
|
30
41
|
end
|
31
42
|
end
|
32
43
|
|
44
|
+
def tables(name = nil)
|
45
|
+
if name
|
46
|
+
@tables[name]
|
47
|
+
else
|
48
|
+
ActiveSupport::Deprecation.warn('call tables with a name!')
|
49
|
+
@tables.dup
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
33
53
|
# Get the columns for a table
|
34
54
|
def columns(table = nil)
|
35
55
|
if table
|
36
56
|
@columns[table]
|
37
57
|
else
|
38
|
-
|
58
|
+
ActiveSupport::Deprecation.warn('call columns with a table name!')
|
59
|
+
@columns.dup
|
39
60
|
end
|
40
61
|
end
|
41
62
|
|
@@ -45,7 +66,8 @@ module ActiveRecord
|
|
45
66
|
if table
|
46
67
|
@columns_hash[table]
|
47
68
|
else
|
48
|
-
|
69
|
+
ActiveSupport::Deprecation.warn('call columns_hash with a table name!')
|
70
|
+
@columns_hash.dup
|
49
71
|
end
|
50
72
|
end
|
51
73
|
|
@@ -58,6 +80,12 @@ module ActiveRecord
|
|
58
80
|
@version = nil
|
59
81
|
end
|
60
82
|
|
83
|
+
def size
|
84
|
+
[@columns, @columns_hash, @primary_keys, @tables].map { |x|
|
85
|
+
x.size
|
86
|
+
}.inject :+
|
87
|
+
end
|
88
|
+
|
61
89
|
# Clear out internal caches for table with +table_name+.
|
62
90
|
def clear_table_cache!(table_name)
|
63
91
|
@columns.delete table_name
|
@@ -69,9 +97,9 @@ module ActiveRecord
|
|
69
97
|
def marshal_dump
|
70
98
|
# if we get current version during initialization, it happens stack over flow.
|
71
99
|
@version = ActiveRecord::Migrator.current_version
|
72
|
-
[@version] + [
|
73
|
-
|
74
|
-
|
100
|
+
[@version] + [@columns, @columns_hash, @primary_keys, @tables].map { |val|
|
101
|
+
Hash[val]
|
102
|
+
}
|
75
103
|
end
|
76
104
|
|
77
105
|
def marshal_load(array)
|
@@ -87,7 +115,7 @@ module ActiveRecord
|
|
87
115
|
end
|
88
116
|
|
89
117
|
@columns_hash.default_proc = Proc.new do |h, table_name|
|
90
|
-
h[table_name] = Hash[columns
|
118
|
+
h[table_name] = Hash[columns(table_name).map { |col|
|
91
119
|
[col.name, col]
|
92
120
|
}]
|
93
121
|
end
|
@@ -6,9 +6,9 @@ gem 'sqlite3', '~> 1.3.6'
|
|
6
6
|
require 'sqlite3'
|
7
7
|
|
8
8
|
module ActiveRecord
|
9
|
-
module ConnectionHandling
|
9
|
+
module ConnectionHandling # :nodoc:
|
10
10
|
# sqlite3 adapter reuses sqlite_connection.
|
11
|
-
def sqlite3_connection(config)
|
11
|
+
def sqlite3_connection(config)
|
12
12
|
# Require database.
|
13
13
|
unless config[:database]
|
14
14
|
raise ArgumentError, "No database file specified. Missing argument: database"
|
@@ -113,7 +113,7 @@ module ActiveRecord
|
|
113
113
|
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
|
114
114
|
@visitor = Arel::Visitors::SQLite.new self
|
115
115
|
else
|
116
|
-
@visitor =
|
116
|
+
@visitor = unprepared_visitor
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
@@ -458,7 +458,7 @@ module ActiveRecord
|
|
458
458
|
|
459
459
|
def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
|
460
460
|
alter_table(table_name) do |definition|
|
461
|
-
definition.
|
461
|
+
definition.remove_column column_name
|
462
462
|
end
|
463
463
|
end
|
464
464
|
|
@@ -583,9 +583,17 @@ module ActiveRecord
|
|
583
583
|
quoted_columns = columns.map { |col| quote_column_name(col) } * ','
|
584
584
|
|
585
585
|
quoted_to = quote_table_name(to)
|
586
|
+
|
587
|
+
raw_column_mappings = Hash[columns(from).map { |c| [c.name, c] }]
|
588
|
+
|
586
589
|
exec_query("SELECT * FROM #{quote_table_name(from)}").each do |row|
|
587
590
|
sql = "INSERT INTO #{quoted_to} (#{quoted_columns}) VALUES ("
|
588
|
-
|
591
|
+
|
592
|
+
column_values = columns.map do |col|
|
593
|
+
quote(row[column_mappings[col]], raw_column_mappings[col])
|
594
|
+
end
|
595
|
+
|
596
|
+
sql << column_values * ', '
|
589
597
|
sql << ')'
|
590
598
|
exec_query sql
|
591
599
|
end
|
@@ -15,15 +15,15 @@ module ActiveRecord
|
|
15
15
|
# Example for SQLite database:
|
16
16
|
#
|
17
17
|
# ActiveRecord::Base.establish_connection(
|
18
|
-
# adapter:
|
19
|
-
# database:
|
18
|
+
# adapter: "sqlite",
|
19
|
+
# database: "path/to/dbfile"
|
20
20
|
# )
|
21
21
|
#
|
22
22
|
# Also accepts keys as strings (for parsing from YAML for example):
|
23
23
|
#
|
24
24
|
# ActiveRecord::Base.establish_connection(
|
25
|
-
# "adapter"
|
26
|
-
# "database"
|
25
|
+
# "adapter" => "sqlite",
|
26
|
+
# "database" => "path/to/dbfile"
|
27
27
|
# )
|
28
28
|
#
|
29
29
|
# Or a URL:
|
@@ -54,11 +54,11 @@ module ActiveRecord
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def connection_id
|
57
|
-
|
57
|
+
ActiveRecord::RuntimeRegistry.connection_id
|
58
58
|
end
|
59
59
|
|
60
60
|
def connection_id=(connection_id)
|
61
|
-
|
61
|
+
ActiveRecord::RuntimeRegistry.connection_id = connection_id
|
62
62
|
end
|
63
63
|
|
64
64
|
# Returns the configuration of the associated connection as a hash:
|
@@ -79,7 +79,7 @@ module ActiveRecord
|
|
79
79
|
connection_handler.retrieve_connection(self)
|
80
80
|
end
|
81
81
|
|
82
|
-
# Returns true if Active Record is connected.
|
82
|
+
# Returns +true+ if Active Record is connected.
|
83
83
|
def connected?
|
84
84
|
connection_handler.connected?(self)
|
85
85
|
end
|
data/lib/active_record/core.rb
CHANGED
@@ -69,8 +69,25 @@ module ActiveRecord
|
|
69
69
|
mattr_accessor :timestamped_migrations, instance_writer: false
|
70
70
|
self.timestamped_migrations = true
|
71
71
|
|
72
|
-
|
73
|
-
|
72
|
+
##
|
73
|
+
# :singleton-method:
|
74
|
+
# Disable implicit join references. This feature was deprecated with Rails 4.
|
75
|
+
# If you don't make use of implicit references but still see deprecation warnings
|
76
|
+
# you can disable the feature entirely. This will be the default with Rails 4.1.
|
77
|
+
mattr_accessor :disable_implicit_join_references, instance_writer: false
|
78
|
+
self.disable_implicit_join_references = false
|
79
|
+
|
80
|
+
class_attribute :default_connection_handler, instance_writer: false
|
81
|
+
|
82
|
+
def self.connection_handler
|
83
|
+
ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.connection_handler=(handler)
|
87
|
+
ActiveRecord::RuntimeRegistry.connection_handler = handler
|
88
|
+
end
|
89
|
+
|
90
|
+
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
74
91
|
end
|
75
92
|
|
76
93
|
module ClassMethods
|
@@ -168,6 +185,7 @@ module ActiveRecord
|
|
168
185
|
@columns_hash = self.class.column_types.dup
|
169
186
|
|
170
187
|
init_internals
|
188
|
+
init_changed_attributes
|
171
189
|
ensure_proper_type
|
172
190
|
populate_with_current_scope_attributes
|
173
191
|
|
@@ -238,9 +256,7 @@ module ActiveRecord
|
|
238
256
|
run_callbacks(:initialize) unless _initialize_callbacks.empty?
|
239
257
|
|
240
258
|
@changed_attributes = {}
|
241
|
-
|
242
|
-
@changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @attributes[attr])
|
243
|
-
end
|
259
|
+
init_changed_attributes
|
244
260
|
|
245
261
|
@aggregation_cache = {}
|
246
262
|
@association_cache = {}
|
@@ -291,9 +307,11 @@ module ActiveRecord
|
|
291
307
|
id.hash
|
292
308
|
end
|
293
309
|
|
294
|
-
#
|
310
|
+
# Clone and freeze the attributes hash such that associations are still
|
311
|
+
# accessible, even on destroyed records, but cloned models will not be
|
312
|
+
# frozen.
|
295
313
|
def freeze
|
296
|
-
@attributes.freeze
|
314
|
+
@attributes = @attributes.clone.freeze
|
297
315
|
self
|
298
316
|
end
|
299
317
|
|
@@ -324,12 +342,19 @@ module ActiveRecord
|
|
324
342
|
# also be used to "borrow" the connection to do database work that isn't
|
325
343
|
# easily done without going straight to SQL.
|
326
344
|
def connection
|
345
|
+
ActiveSupport::Deprecation.warn("#connection is deprecated in favour of accessing it via the class")
|
327
346
|
self.class.connection
|
328
347
|
end
|
329
348
|
|
349
|
+
def connection_handler
|
350
|
+
self.class.connection_handler
|
351
|
+
end
|
352
|
+
|
330
353
|
# Returns the contents of the record as a nicely formatted string.
|
331
354
|
def inspect
|
332
|
-
|
355
|
+
# We check defined?(@attributes) not to issue warnings if the object is
|
356
|
+
# allocated but not initialized.
|
357
|
+
inspection = if defined?(@attributes) && @attributes
|
333
358
|
self.class.column_names.collect { |name|
|
334
359
|
if has_attribute?(name)
|
335
360
|
"#{name}: #{attribute_for_inspect(name)}"
|
@@ -418,11 +443,21 @@ module ActiveRecord
|
|
418
443
|
@readonly = false
|
419
444
|
@destroyed = false
|
420
445
|
@marked_for_destruction = false
|
446
|
+
@destroyed_by_association = nil
|
421
447
|
@new_record = true
|
422
448
|
@txn = nil
|
423
449
|
@_start_transaction_state = {}
|
424
450
|
@transaction_state = nil
|
425
451
|
@reflects_state = [false]
|
426
452
|
end
|
453
|
+
|
454
|
+
def init_changed_attributes
|
455
|
+
# Intentionally avoid using #column_defaults since overridden defaults (as is done in
|
456
|
+
# optimistic locking) won't get written unless they get marked as changed
|
457
|
+
self.class.columns.each do |c|
|
458
|
+
attr, orig_value = c.name, c.default
|
459
|
+
@changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @attributes[attr])
|
460
|
+
end
|
461
|
+
end
|
427
462
|
end
|
428
463
|
end
|
@@ -11,7 +11,7 @@ module ActiveRecord
|
|
11
11
|
# ==== Parameters
|
12
12
|
#
|
13
13
|
# * +id+ - The id of the object you wish to reset a counter on.
|
14
|
-
# * +counters+ - One or more
|
14
|
+
# * +counters+ - One or more association counters to reset
|
15
15
|
#
|
16
16
|
# ==== Examples
|
17
17
|
#
|
@@ -21,6 +21,7 @@ module ActiveRecord
|
|
21
21
|
object = find(id)
|
22
22
|
counters.each do |association|
|
23
23
|
has_many_association = reflect_on_association(association.to_sym)
|
24
|
+
raise ArgumentError, "'#{self.name}' has no association called '#{association}'" unless has_many_association
|
24
25
|
|
25
26
|
if has_many_association.is_a? ActiveRecord::Reflection::ThroughReflection
|
26
27
|
has_many_association = has_many_association.through_reflection
|
data/lib/active_record/errors.rb
CHANGED
@@ -57,24 +57,25 @@ module ActiveRecord
|
|
57
57
|
class RecordNotDestroyed < ActiveRecordError
|
58
58
|
end
|
59
59
|
|
60
|
-
#
|
61
|
-
#
|
60
|
+
# Superclass for all database execution errors.
|
61
|
+
#
|
62
|
+
# Wraps the underlying database error as +original_exception+.
|
62
63
|
class StatementInvalid < ActiveRecordError
|
64
|
+
attr_reader :original_exception
|
65
|
+
|
66
|
+
def initialize(message, original_exception = nil)
|
67
|
+
super(message)
|
68
|
+
@original_exception = original_exception
|
69
|
+
end
|
63
70
|
end
|
64
71
|
|
65
72
|
# Raised when SQL statement is invalid and the application gets a blank result.
|
66
73
|
class ThrowResult < ActiveRecordError
|
67
74
|
end
|
68
75
|
|
69
|
-
#
|
70
|
-
#
|
76
|
+
# Defunct wrapper class kept for compatibility.
|
77
|
+
# +StatementInvalid+ wraps the original exception now.
|
71
78
|
class WrappedDatabaseException < StatementInvalid
|
72
|
-
attr_reader :original_exception
|
73
|
-
|
74
|
-
def initialize(message, original_exception)
|
75
|
-
super(message)
|
76
|
-
@original_exception = original_exception
|
77
|
-
end
|
78
79
|
end
|
79
80
|
|
80
81
|
# Raised when a record cannot be inserted because it would violate a uniqueness constraint.
|
@@ -1,21 +1,22 @@
|
|
1
1
|
require 'active_support/lazy_load_hooks'
|
2
|
+
require 'active_record/explain_registry'
|
2
3
|
|
3
4
|
module ActiveRecord
|
4
5
|
module Explain
|
5
|
-
#
|
6
|
+
# Executes the block with the collect flag enabled. Queries are collected
|
7
|
+
# asynchronously by the subscriber and returned.
|
6
8
|
def collecting_queries_for_explain # :nodoc:
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
ExplainRegistry.collect = true
|
10
|
+
yield
|
11
|
+
ExplainRegistry.queries
|
10
12
|
ensure
|
11
|
-
|
12
|
-
current[:available_queries_for_explain] = original
|
13
|
+
ExplainRegistry.reset
|
13
14
|
end
|
14
15
|
|
15
16
|
# Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
|
16
17
|
# Returns a formatted string ready to be logged.
|
17
18
|
def exec_explain(queries) # :nodoc:
|
18
|
-
str = queries
|
19
|
+
str = queries.map do |sql, bind|
|
19
20
|
[].tap do |msg|
|
20
21
|
msg << "EXPLAIN for: #{sql}"
|
21
22
|
unless bind.empty?
|
@@ -30,6 +31,7 @@ module ActiveRecord
|
|
30
31
|
def str.inspect
|
31
32
|
self
|
32
33
|
end
|
34
|
+
|
33
35
|
str
|
34
36
|
end
|
35
37
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'active_support/per_thread_registry'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
# This is a thread locals registry for EXPLAIN. For example
|
5
|
+
#
|
6
|
+
# ActiveRecord::ExplainRegistry.queries
|
7
|
+
#
|
8
|
+
# returns the collected queries local to the current thread.
|
9
|
+
#
|
10
|
+
# See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
|
11
|
+
# for further details.
|
12
|
+
class ExplainRegistry # :nodoc:
|
13
|
+
extend ActiveSupport::PerThreadRegistry
|
14
|
+
|
15
|
+
attr_accessor :queries, :collect
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
reset
|
19
|
+
end
|
20
|
+
|
21
|
+
def collect?
|
22
|
+
@collect
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset
|
26
|
+
@collect = false
|
27
|
+
@queries = []
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_support/notifications'
|
2
|
+
require 'active_record/explain_registry'
|
2
3
|
|
3
4
|
module ActiveRecord
|
4
5
|
class ExplainSubscriber # :nodoc:
|
@@ -7,8 +8,8 @@ module ActiveRecord
|
|
7
8
|
end
|
8
9
|
|
9
10
|
def finish(name, id, payload)
|
10
|
-
if
|
11
|
-
queries << payload.values_at(:sql, :binds)
|
11
|
+
if ExplainRegistry.collect? && !ignore_payload?(payload)
|
12
|
+
ExplainRegistry.queries << payload.values_at(:sql, :binds)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
@@ -24,7 +24,6 @@ module ActiveRecord
|
|
24
24
|
rows.each(&block)
|
25
25
|
end
|
26
26
|
|
27
|
-
RESCUE_ERRORS = [ ArgumentError, Psych::SyntaxError ] # :nodoc:
|
28
27
|
|
29
28
|
private
|
30
29
|
def rows
|
@@ -32,7 +31,7 @@ module ActiveRecord
|
|
32
31
|
|
33
32
|
begin
|
34
33
|
data = YAML.load(render(IO.read(@file)))
|
35
|
-
rescue
|
34
|
+
rescue ArgumentError, Psych::SyntaxError => error
|
36
35
|
raise Fixture::FormatError, "a YAML error occurred parsing #{@file}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{error.class}: #{error}", error.backtrace
|
37
36
|
end
|
38
37
|
@rows = data ? validate(data).to_a : []
|
@@ -708,11 +708,18 @@ module ActiveRecord
|
|
708
708
|
module TestFixtures
|
709
709
|
extend ActiveSupport::Concern
|
710
710
|
|
711
|
-
|
712
|
-
|
713
|
-
|
711
|
+
def before_setup
|
712
|
+
setup_fixtures
|
713
|
+
super
|
714
|
+
end
|
715
|
+
|
716
|
+
def after_teardown
|
717
|
+
super
|
718
|
+
teardown_fixtures
|
719
|
+
end
|
714
720
|
|
715
|
-
|
721
|
+
included do
|
722
|
+
class_attribute :fixture_path, :instance_writer => false
|
716
723
|
class_attribute :fixture_table_names
|
717
724
|
class_attribute :fixture_class_names
|
718
725
|
class_attribute :use_transactional_fixtures
|
@@ -752,7 +759,7 @@ module ActiveRecord
|
|
752
759
|
def fixtures(*fixture_set_names)
|
753
760
|
if fixture_set_names.first == :all
|
754
761
|
fixture_set_names = Dir["#{fixture_path}/**/*.{yml}"]
|
755
|
-
fixture_set_names.map! { |f| f[(fixture_path.size + 1)..-5] }
|
762
|
+
fixture_set_names.map! { |f| f[(fixture_path.to_s.size + 1)..-5] }
|
756
763
|
else
|
757
764
|
fixture_set_names = fixture_set_names.flatten.map { |n| n.to_s }
|
758
765
|
end
|
@@ -765,8 +772,7 @@ module ActiveRecord
|
|
765
772
|
def try_to_load_dependency(file_name)
|
766
773
|
require_dependency file_name
|
767
774
|
rescue LoadError => e
|
768
|
-
# Let's hope the developer has included it
|
769
|
-
|
775
|
+
# Let's hope the developer has included it
|
770
776
|
# Let's warn in case this is a subdependency, otherwise
|
771
777
|
# subdependency error messages are totally cryptic
|
772
778
|
if ActiveRecord::Base.logger
|