activerecord 3.2.22.4 → 4.0.13

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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2799 -617
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +23 -32
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +40 -34
  7. data/lib/active_record/association_relation.rb +22 -0
  8. data/lib/active_record/associations/alias_tracker.rb +4 -2
  9. data/lib/active_record/associations/association.rb +60 -46
  10. data/lib/active_record/associations/association_scope.rb +46 -40
  11. data/lib/active_record/associations/belongs_to_association.rb +17 -4
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  13. data/lib/active_record/associations/builder/association.rb +81 -28
  14. data/lib/active_record/associations/builder/belongs_to.rb +73 -56
  15. data/lib/active_record/associations/builder/collection_association.rb +54 -40
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -64
  18. data/lib/active_record/associations/builder/has_one.rb +13 -50
  19. data/lib/active_record/associations/builder/singular_association.rb +13 -13
  20. data/lib/active_record/associations/collection_association.rb +130 -96
  21. data/lib/active_record/associations/collection_proxy.rb +916 -63
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +15 -13
  23. data/lib/active_record/associations/has_many_association.rb +35 -8
  24. data/lib/active_record/associations/has_many_through_association.rb +37 -17
  25. data/lib/active_record/associations/has_one_association.rb +42 -19
  26. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_association.rb +39 -22
  28. data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
  29. data/lib/active_record/associations/join_dependency/join_part.rb +21 -8
  30. data/lib/active_record/associations/join_dependency.rb +30 -9
  31. data/lib/active_record/associations/join_helper.rb +1 -11
  32. data/lib/active_record/associations/preloader/association.rb +29 -33
  33. data/lib/active_record/associations/preloader/collection_association.rb +1 -1
  34. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +2 -2
  35. data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
  36. data/lib/active_record/associations/preloader/has_one.rb +1 -1
  37. data/lib/active_record/associations/preloader/through_association.rb +13 -17
  38. data/lib/active_record/associations/preloader.rb +20 -43
  39. data/lib/active_record/associations/singular_association.rb +11 -11
  40. data/lib/active_record/associations/through_association.rb +3 -3
  41. data/lib/active_record/associations.rb +223 -282
  42. data/lib/active_record/attribute_assignment.rb +134 -154
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
  44. data/lib/active_record/attribute_methods/dirty.rb +36 -29
  45. data/lib/active_record/attribute_methods/primary_key.rb +45 -31
  46. data/lib/active_record/attribute_methods/query.rb +5 -4
  47. data/lib/active_record/attribute_methods/read.rb +67 -90
  48. data/lib/active_record/attribute_methods/serialization.rb +133 -70
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +51 -45
  50. data/lib/active_record/attribute_methods/write.rb +34 -39
  51. data/lib/active_record/attribute_methods.rb +268 -108
  52. data/lib/active_record/autosave_association.rb +80 -73
  53. data/lib/active_record/base.rb +54 -451
  54. data/lib/active_record/callbacks.rb +60 -22
  55. data/lib/active_record/coders/yaml_column.rb +18 -21
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +347 -197
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +146 -138
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -19
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +19 -3
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +151 -142
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +499 -217
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +208 -0
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +209 -44
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +169 -61
  67. data/lib/active_record/connection_adapters/column.rb +67 -36
  68. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +28 -29
  70. data/lib/active_record/connection_adapters/mysql_adapter.rb +200 -73
  71. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +98 -0
  72. data/lib/active_record/connection_adapters/postgresql/cast.rb +160 -0
  73. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +240 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid.rb +374 -0
  75. data/lib/active_record/connection_adapters/postgresql/quoting.rb +183 -0
  76. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  77. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +508 -0
  78. data/lib/active_record/connection_adapters/postgresql_adapter.rb +544 -899
  79. data/lib/active_record/connection_adapters/schema_cache.rb +76 -16
  80. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +595 -16
  81. data/lib/active_record/connection_handling.rb +98 -0
  82. data/lib/active_record/core.rb +472 -0
  83. data/lib/active_record/counter_cache.rb +107 -108
  84. data/lib/active_record/dynamic_matchers.rb +115 -63
  85. data/lib/active_record/errors.rb +36 -18
  86. data/lib/active_record/explain.rb +15 -63
  87. data/lib/active_record/explain_registry.rb +30 -0
  88. data/lib/active_record/explain_subscriber.rb +8 -4
  89. data/lib/active_record/fixture_set/file.rb +55 -0
  90. data/lib/active_record/fixtures.rb +159 -155
  91. data/lib/active_record/inheritance.rb +93 -59
  92. data/lib/active_record/integration.rb +8 -8
  93. data/lib/active_record/locale/en.yml +8 -1
  94. data/lib/active_record/locking/optimistic.rb +39 -43
  95. data/lib/active_record/locking/pessimistic.rb +4 -4
  96. data/lib/active_record/log_subscriber.rb +19 -9
  97. data/lib/active_record/migration/command_recorder.rb +102 -33
  98. data/lib/active_record/migration/join_table.rb +15 -0
  99. data/lib/active_record/migration.rb +411 -173
  100. data/lib/active_record/model_schema.rb +81 -94
  101. data/lib/active_record/nested_attributes.rb +173 -131
  102. data/lib/active_record/null_relation.rb +67 -0
  103. data/lib/active_record/persistence.rb +254 -106
  104. data/lib/active_record/query_cache.rb +18 -36
  105. data/lib/active_record/querying.rb +19 -15
  106. data/lib/active_record/railtie.rb +113 -38
  107. data/lib/active_record/railties/console_sandbox.rb +3 -4
  108. data/lib/active_record/railties/controller_runtime.rb +4 -3
  109. data/lib/active_record/railties/databases.rake +115 -368
  110. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  111. data/lib/active_record/readonly_attributes.rb +7 -3
  112. data/lib/active_record/reflection.rb +110 -61
  113. data/lib/active_record/relation/batches.rb +29 -29
  114. data/lib/active_record/relation/calculations.rb +155 -125
  115. data/lib/active_record/relation/delegation.rb +94 -18
  116. data/lib/active_record/relation/finder_methods.rb +151 -203
  117. data/lib/active_record/relation/merger.rb +188 -0
  118. data/lib/active_record/relation/predicate_builder.rb +85 -42
  119. data/lib/active_record/relation/query_methods.rb +793 -146
  120. data/lib/active_record/relation/spawn_methods.rb +43 -150
  121. data/lib/active_record/relation.rb +293 -173
  122. data/lib/active_record/result.rb +48 -7
  123. data/lib/active_record/runtime_registry.rb +17 -0
  124. data/lib/active_record/sanitization.rb +41 -54
  125. data/lib/active_record/schema.rb +19 -12
  126. data/lib/active_record/schema_dumper.rb +41 -41
  127. data/lib/active_record/schema_migration.rb +46 -0
  128. data/lib/active_record/scoping/default.rb +56 -52
  129. data/lib/active_record/scoping/named.rb +78 -103
  130. data/lib/active_record/scoping.rb +54 -124
  131. data/lib/active_record/serialization.rb +6 -2
  132. data/lib/active_record/serializers/xml_serializer.rb +9 -15
  133. data/lib/active_record/statement_cache.rb +26 -0
  134. data/lib/active_record/store.rb +131 -15
  135. data/lib/active_record/tasks/database_tasks.rb +204 -0
  136. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  137. data/lib/active_record/tasks/mysql_database_tasks.rb +144 -0
  138. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  139. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  140. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  141. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  142. data/lib/active_record/test_case.rb +67 -38
  143. data/lib/active_record/timestamp.rb +16 -11
  144. data/lib/active_record/transactions.rb +73 -51
  145. data/lib/active_record/validations/associated.rb +19 -13
  146. data/lib/active_record/validations/presence.rb +65 -0
  147. data/lib/active_record/validations/uniqueness.rb +110 -57
  148. data/lib/active_record/validations.rb +18 -17
  149. data/lib/active_record/version.rb +7 -6
  150. data/lib/active_record.rb +63 -45
  151. data/lib/rails/generators/active_record/migration/migration_generator.rb +45 -8
  152. data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
  153. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  154. data/lib/rails/generators/active_record/model/model_generator.rb +5 -4
  155. data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
  156. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  157. data/lib/rails/generators/active_record.rb +3 -5
  158. metadata +43 -29
  159. data/examples/associations.png +0 -0
  160. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  161. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  162. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  163. data/lib/active_record/dynamic_finder_match.rb +0 -68
  164. data/lib/active_record/dynamic_scope_match.rb +0 -23
  165. data/lib/active_record/fixtures/file.rb +0 -65
  166. data/lib/active_record/identity_map.rb +0 -162
  167. data/lib/active_record/observer.rb +0 -121
  168. data/lib/active_record/session_store.rb +0 -360
  169. data/lib/rails/generators/active_record/migration.rb +0 -15
  170. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  171. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  172. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  173. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -8,66 +8,125 @@ module ActiveRecord
8
8
  # * add_index
9
9
  # * add_timestamps
10
10
  # * create_table
11
+ # * create_join_table
11
12
  # * remove_timestamps
12
13
  # * rename_column
13
14
  # * rename_index
14
15
  # * rename_table
15
16
  class CommandRecorder
16
- attr_accessor :commands, :delegate
17
+ include JoinTable
18
+
19
+ attr_accessor :commands, :delegate, :reverting
17
20
 
18
21
  def initialize(delegate = nil)
19
22
  @commands = []
20
23
  @delegate = delegate
24
+ @reverting = false
25
+ end
26
+
27
+ # While executing the given block, the recorded will be in reverting mode.
28
+ # All commands recorded will end up being recorded reverted
29
+ # and in reverse order.
30
+ # For example:
31
+ #
32
+ # recorder.revert{ recorder.record(:rename_table, [:old, :new]) }
33
+ # # same effect as recorder.record(:rename_table, [:new, :old])
34
+ def revert
35
+ @reverting = !@reverting
36
+ previous = @commands
37
+ @commands = []
38
+ yield
39
+ ensure
40
+ @commands = previous.concat(@commands.reverse)
41
+ @reverting = !@reverting
21
42
  end
22
43
 
23
44
  # record +command+. +command+ should be a method name and arguments.
24
45
  # For example:
25
46
  #
26
47
  # recorder.record(:method_name, [:arg1, :arg2])
27
- def record(*command)
28
- @commands << command
48
+ def record(*command, &block)
49
+ if @reverting
50
+ @commands << inverse_of(*command, &block)
51
+ else
52
+ @commands << (command << block)
53
+ end
29
54
  end
30
55
 
31
- # Returns a list that represents commands that are the inverse of the
32
- # commands stored in +commands+. For example:
56
+ # Returns the inverse of the given command. For example:
33
57
  #
34
- # recorder.record(:rename_table, [:old, :new])
35
- # recorder.inverse # => [:rename_table, [:new, :old]]
58
+ # recorder.inverse_of(:rename_table, [:old, :new])
59
+ # # => [:rename_table, [:new, :old]]
36
60
  #
37
61
  # This method will raise an +IrreversibleMigration+ exception if it cannot
38
- # invert the +commands+.
39
- def inverse
40
- @commands.reverse.map { |name, args|
41
- method = :"invert_#{name}"
42
- raise IrreversibleMigration unless respond_to?(method, true)
43
- send(method, args)
44
- }
62
+ # invert the +command+.
63
+ def inverse_of(command, args, &block)
64
+ method = :"invert_#{command}"
65
+ raise IrreversibleMigration unless respond_to?(method, true)
66
+ send(method, args, &block)
45
67
  end
46
68
 
47
69
  def respond_to?(*args) # :nodoc:
48
70
  super || delegate.respond_to?(*args)
49
71
  end
50
72
 
51
- [:create_table, :change_table, :rename_table, :add_column, :remove_column, :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps, :change_column, :change_column_default].each do |method|
73
+ [:create_table, :create_join_table, :rename_table, :add_column, :remove_column,
74
+ :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
75
+ :change_column_default, :add_reference, :remove_reference, :transaction,
76
+ :drop_join_table, :drop_table, :execute_block,
77
+ :change_column, :execute, :remove_columns, # irreversible methods need to be here too
78
+ ].each do |method|
52
79
  class_eval <<-EOV, __FILE__, __LINE__ + 1
53
- def #{method}(*args) # def create_table(*args)
54
- record(:"#{method}", args) # record(:create_table, args)
55
- end # end
80
+ def #{method}(*args, &block) # def create_table(*args, &block)
81
+ record(:"#{method}", args, &block) # record(:create_table, args, &block)
82
+ end # end
56
83
  EOV
57
84
  end
85
+ alias :add_belongs_to :add_reference
86
+ alias :remove_belongs_to :remove_reference
87
+
88
+ def change_table(table_name, options = {})
89
+ yield delegate.update_table_definition(table_name, self)
90
+ end
58
91
 
59
92
  private
60
93
 
61
- def invert_create_table(args)
62
- [:drop_table, [args.first]]
94
+ module StraightReversions
95
+ private
96
+ { transaction: :transaction,
97
+ execute_block: :execute_block,
98
+ create_table: :drop_table,
99
+ create_join_table: :drop_join_table,
100
+ add_column: :remove_column,
101
+ add_timestamps: :remove_timestamps,
102
+ add_reference: :remove_reference,
103
+ }.each do |cmd, inv|
104
+ [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
105
+ class_eval <<-EOV, __FILE__, __LINE__ + 1
106
+ def invert_#{method}(args, &block) # def invert_create_table(args, &block)
107
+ [:#{inverse}, args, block] # [:drop_table, args, block]
108
+ end # end
109
+ EOV
110
+ end
111
+ end
112
+ end
113
+
114
+ include StraightReversions
115
+
116
+ def invert_drop_table(args, &block)
117
+ if args.size == 1 && block == nil
118
+ raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
119
+ end
120
+ super
63
121
  end
64
122
 
65
123
  def invert_rename_table(args)
66
124
  [:rename_table, args.reverse]
67
125
  end
68
126
 
69
- def invert_add_column(args)
70
- [:remove_column, args.first(2)]
127
+ def invert_remove_column(args)
128
+ raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
129
+ super
71
130
  end
72
131
 
73
132
  def invert_rename_index(args)
@@ -80,26 +139,36 @@ module ActiveRecord
80
139
 
81
140
  def invert_add_index(args)
82
141
  table, columns, options = *args
83
- index_name = options.try(:[], :name)
84
- options_hash = index_name ? {:name => index_name} : {:column => columns}
142
+ options ||= {}
143
+
144
+ index_name = options[:name]
145
+ options_hash = index_name ? { name: index_name } : { column: columns }
146
+
85
147
  [:remove_index, [table, options_hash]]
86
148
  end
87
149
 
88
- def invert_remove_timestamps(args)
89
- [:add_timestamps, args]
90
- end
150
+ def invert_remove_index(args)
151
+ table, options = *args
152
+
153
+ unless options && options.is_a?(Hash) && options[:column]
154
+ raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option."
155
+ end
91
156
 
92
- def invert_add_timestamps(args)
93
- [:remove_timestamps, args]
157
+ options = options.dup
158
+ [:add_index, [table, options.delete(:column), options]]
94
159
  end
95
160
 
161
+ alias :invert_add_belongs_to :invert_add_reference
162
+ alias :invert_remove_belongs_to :invert_remove_reference
163
+
96
164
  # Forwards any missing method call to the \target.
97
165
  def method_missing(method, *args, &block)
98
- @delegate.send(method, *args, &block)
99
- rescue NoMethodError => e
100
- raise e, e.message.sub(/ for #<.*$/, " via proxy for #{@delegate}")
166
+ if @delegate.respond_to?(method)
167
+ @delegate.send(method, *args, &block)
168
+ else
169
+ super
170
+ end
101
171
  end
102
-
103
172
  end
104
173
  end
105
174
  end
@@ -0,0 +1,15 @@
1
+ module ActiveRecord
2
+ class Migration
3
+ module JoinTable #:nodoc:
4
+ private
5
+
6
+ def find_join_table_name(table_1, table_2, options = {})
7
+ options.delete(:table_name) || join_table_name(table_1, table_2)
8
+ end
9
+
10
+ def join_table_name(table_1, table_2)
11
+ [table_1.to_s, table_2.to_s].sort.join("_").to_sym
12
+ end
13
+ end
14
+ end
15
+ end