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.

Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +573 -30
  3. data/README.rdoc +3 -3
  4. data/lib/active_record.rb +8 -2
  5. data/lib/active_record/associations.rb +16 -9
  6. data/lib/active_record/associations/association.rb +8 -6
  7. data/lib/active_record/associations/association_scope.rb +2 -1
  8. data/lib/active_record/associations/belongs_to_association.rb +2 -2
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  10. data/lib/active_record/associations/builder/belongs_to.rb +37 -5
  11. data/lib/active_record/associations/collection_association.rb +38 -14
  12. data/lib/active_record/associations/collection_proxy.rb +18 -15
  13. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +3 -3
  14. data/lib/active_record/associations/has_many_association.rb +4 -3
  15. data/lib/active_record/associations/has_many_through_association.rb +1 -1
  16. data/lib/active_record/associations/has_one_association.rb +1 -1
  17. data/lib/active_record/associations/join_dependency.rb +29 -8
  18. data/lib/active_record/associations/join_dependency/join_association.rb +26 -6
  19. data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
  20. data/lib/active_record/associations/join_dependency/join_part.rb +6 -6
  21. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +1 -1
  22. data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
  23. data/lib/active_record/associations/through_association.rb +1 -1
  24. data/lib/active_record/attribute_assignment.rb +5 -5
  25. data/lib/active_record/attribute_methods.rb +20 -5
  26. data/lib/active_record/attribute_methods/dirty.rb +5 -1
  27. data/lib/active_record/attribute_methods/primary_key.rb +1 -1
  28. data/lib/active_record/attribute_methods/serialization.rb +9 -2
  29. data/lib/active_record/autosave_association.rb +19 -5
  30. data/lib/active_record/base.rb +3 -3
  31. data/lib/active_record/callbacks.rb +1 -1
  32. data/lib/active_record/coders/yaml_column.rb +8 -13
  33. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +3 -9
  34. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -1
  35. data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -1
  36. data/lib/active_record/connection_adapters/abstract/quoting.rb +2 -8
  37. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +60 -61
  38. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +13 -2
  39. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +291 -153
  40. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -1
  41. data/lib/active_record/connection_adapters/abstract_adapter.rb +92 -1
  42. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +55 -29
  43. data/lib/active_record/connection_adapters/column.rb +4 -4
  44. data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
  45. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -3
  46. data/lib/active_record/connection_adapters/mysql_adapter.rb +5 -5
  47. data/lib/active_record/connection_adapters/postgresql/cast.rb +22 -2
  48. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -6
  49. data/lib/active_record/connection_adapters/postgresql/quoting.rb +26 -13
  50. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +50 -9
  51. data/lib/active_record/connection_adapters/postgresql_adapter.rb +53 -24
  52. data/lib/active_record/connection_adapters/schema_cache.rb +35 -7
  53. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +13 -5
  54. data/lib/active_record/connection_handling.rb +7 -7
  55. data/lib/active_record/core.rb +43 -8
  56. data/lib/active_record/counter_cache.rb +2 -1
  57. data/lib/active_record/errors.rb +11 -10
  58. data/lib/active_record/explain.rb +9 -7
  59. data/lib/active_record/explain_registry.rb +30 -0
  60. data/lib/active_record/explain_subscriber.rb +3 -2
  61. data/lib/active_record/fixture_set/file.rb +1 -2
  62. data/lib/active_record/fixtures.rb +13 -7
  63. data/lib/active_record/inheritance.rb +12 -4
  64. data/lib/active_record/integration.rb +3 -3
  65. data/lib/active_record/locking/optimistic.rb +2 -2
  66. data/lib/active_record/log_subscriber.rb +2 -2
  67. data/lib/active_record/migration.rb +69 -21
  68. data/lib/active_record/model_schema.rb +1 -1
  69. data/lib/active_record/nested_attributes.rb +98 -46
  70. data/lib/active_record/persistence.rb +3 -3
  71. data/lib/active_record/querying.rb +1 -1
  72. data/lib/active_record/railtie.rb +18 -4
  73. data/lib/active_record/railties/console_sandbox.rb +3 -2
  74. data/lib/active_record/railties/controller_runtime.rb +2 -1
  75. data/lib/active_record/railties/databases.rake +38 -80
  76. data/lib/active_record/reflection.rb +36 -3
  77. data/lib/active_record/relation.rb +18 -8
  78. data/lib/active_record/relation/calculations.rb +10 -5
  79. data/lib/active_record/relation/delegation.rb +3 -5
  80. data/lib/active_record/relation/finder_methods.rb +27 -14
  81. data/lib/active_record/relation/merger.rb +30 -2
  82. data/lib/active_record/relation/predicate_builder.rb +1 -6
  83. data/lib/active_record/relation/query_methods.rb +113 -16
  84. data/lib/active_record/runtime_registry.rb +17 -0
  85. data/lib/active_record/schema_dumper.rb +5 -1
  86. data/lib/active_record/schema_migration.rb +8 -5
  87. data/lib/active_record/scoping.rb +56 -2
  88. data/lib/active_record/scoping/default.rb +12 -11
  89. data/lib/active_record/scoping/named.rb +7 -3
  90. data/lib/active_record/serialization.rb +1 -1
  91. data/lib/active_record/statement_cache.rb +26 -0
  92. data/lib/active_record/tasks/database_tasks.rb +55 -10
  93. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  94. data/lib/active_record/tasks/mysql_database_tasks.rb +7 -2
  95. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  96. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  97. data/lib/active_record/timestamp.rb +6 -0
  98. data/lib/active_record/transactions.rb +7 -3
  99. data/lib/active_record/validations.rb +1 -2
  100. data/lib/active_record/validations/uniqueness.rb +7 -3
  101. data/lib/active_record/version.rb +7 -6
  102. data/lib/rails/generators/active_record/migration/migration_generator.rb +9 -2
  103. data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
  104. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  105. data/lib/rails/generators/active_record/model/templates/model.rb +4 -1
  106. metadata +17 -12
  107. 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 :primary_keys, :tables, :version
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
- @columns
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
- @columns_hash
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] + [:@columns, :@columns_hash, :@primary_keys, :@tables].map do |val|
73
- self.instance_variable_get(val).inject({}) { |h, v| h[v[0]] = v[1]; h }
74
- end
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[table_name].map { |col|
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) # :nodoc:
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 = BindSubstitution.new self
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.columns.delete(definition[column_name])
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
- sql << columns.map {|col| quote row[column_mappings[col]]} * ', '
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: "sqlite",
19
- # database: "path/to/dbfile"
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" => "sqlite",
26
- # "database" => "path/to/dbfile"
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
- Thread.current['ActiveRecord::Base.connection_id']
57
+ ActiveRecord::RuntimeRegistry.connection_id
58
58
  end
59
59
 
60
60
  def connection_id=(connection_id)
61
- Thread.current['ActiveRecord::Base.connection_id'] = connection_id
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
@@ -69,8 +69,25 @@ module ActiveRecord
69
69
  mattr_accessor :timestamped_migrations, instance_writer: false
70
70
  self.timestamped_migrations = true
71
71
 
72
- class_attribute :connection_handler, instance_writer: false
73
- self.connection_handler = ConnectionAdapters::ConnectionHandler.new
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
- self.class.column_defaults.each do |attr, orig_value|
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
- # Freeze the attributes hash such that associations are still accessible, even on destroyed records.
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
- inspection = if @attributes
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 counter names to reset
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
@@ -57,24 +57,25 @@ module ActiveRecord
57
57
  class RecordNotDestroyed < ActiveRecordError
58
58
  end
59
59
 
60
- # Raised when SQL statement cannot be executed by the database (for example, it's often the case for
61
- # MySQL when Ruby driver used is too old).
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
- # Parent class for all specific exceptions which wrap database driver exceptions
70
- # provides access to the original exception also.
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
- # Relation#explain needs to be able to collect the queries.
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
- current = Thread.current
8
- original, current[:available_queries_for_explain] = current[:available_queries_for_explain], []
9
- return yield, current[:available_queries_for_explain]
9
+ ExplainRegistry.collect = true
10
+ yield
11
+ ExplainRegistry.queries
10
12
  ensure
11
- # Note that the return value above does not depend on this assigment.
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 && queries.map do |sql, bind|
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 queries = Thread.current[:available_queries_for_explain]
11
- queries << payload.values_at(:sql, :binds) unless ignore_payload?(payload)
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 *RESCUE_ERRORS => error
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
- included do
712
- setup :setup_fixtures
713
- teardown :teardown_fixtures
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
- class_attribute :fixture_path
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 himself
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