activerecord 3.0.0 → 4.0.0

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 (181) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2102 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +35 -44
  5. data/examples/performance.rb +110 -100
  6. data/lib/active_record/aggregations.rb +59 -75
  7. data/lib/active_record/associations/alias_tracker.rb +76 -0
  8. data/lib/active_record/associations/association.rb +248 -0
  9. data/lib/active_record/associations/association_scope.rb +135 -0
  10. data/lib/active_record/associations/belongs_to_association.rb +60 -59
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -59
  12. data/lib/active_record/associations/builder/association.rb +108 -0
  13. data/lib/active_record/associations/builder/belongs_to.rb +98 -0
  14. data/lib/active_record/associations/builder/collection_association.rb +89 -0
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +39 -0
  16. data/lib/active_record/associations/builder/has_many.rb +15 -0
  17. data/lib/active_record/associations/builder/has_one.rb +25 -0
  18. data/lib/active_record/associations/builder/singular_association.rb +32 -0
  19. data/lib/active_record/associations/collection_association.rb +608 -0
  20. data/lib/active_record/associations/collection_proxy.rb +986 -0
  21. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +40 -112
  22. data/lib/active_record/associations/has_many_association.rb +83 -76
  23. data/lib/active_record/associations/has_many_through_association.rb +147 -66
  24. data/lib/active_record/associations/has_one_association.rb +67 -108
  25. data/lib/active_record/associations/has_one_through_association.rb +21 -25
  26. data/lib/active_record/associations/join_dependency/join_association.rb +174 -0
  27. data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
  28. data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
  29. data/lib/active_record/associations/join_dependency.rb +235 -0
  30. data/lib/active_record/associations/join_helper.rb +45 -0
  31. data/lib/active_record/associations/preloader/association.rb +121 -0
  32. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  33. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  34. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
  35. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  36. data/lib/active_record/associations/preloader/has_many_through.rb +19 -0
  37. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  38. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  39. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  40. data/lib/active_record/associations/preloader/through_association.rb +63 -0
  41. data/lib/active_record/associations/preloader.rb +178 -0
  42. data/lib/active_record/associations/singular_association.rb +64 -0
  43. data/lib/active_record/associations/through_association.rb +87 -0
  44. data/lib/active_record/associations.rb +512 -1224
  45. data/lib/active_record/attribute_assignment.rb +201 -0
  46. data/lib/active_record/attribute_methods/before_type_cast.rb +49 -12
  47. data/lib/active_record/attribute_methods/dirty.rb +51 -28
  48. data/lib/active_record/attribute_methods/primary_key.rb +94 -22
  49. data/lib/active_record/attribute_methods/query.rb +5 -4
  50. data/lib/active_record/attribute_methods/read.rb +63 -72
  51. data/lib/active_record/attribute_methods/serialization.rb +162 -0
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -41
  53. data/lib/active_record/attribute_methods/write.rb +39 -13
  54. data/lib/active_record/attribute_methods.rb +362 -29
  55. data/lib/active_record/autosave_association.rb +132 -75
  56. data/lib/active_record/base.rb +83 -1627
  57. data/lib/active_record/callbacks.rb +69 -47
  58. data/lib/active_record/coders/yaml_column.rb +38 -0
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +411 -138
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +21 -11
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -173
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +36 -22
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +82 -25
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +176 -414
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +562 -232
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +281 -53
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +782 -0
  70. data/lib/active_record/connection_adapters/column.rb +318 -0
  71. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +273 -0
  73. data/lib/active_record/connection_adapters/mysql_adapter.rb +365 -450
  74. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
  75. data/lib/active_record/connection_adapters/postgresql/cast.rb +152 -0
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
  77. data/lib/active_record/connection_adapters/postgresql/oid.rb +366 -0
  78. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -0
  79. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  80. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +489 -0
  81. data/lib/active_record/connection_adapters/postgresql_adapter.rb +672 -752
  82. data/lib/active_record/connection_adapters/schema_cache.rb +129 -0
  83. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +588 -17
  84. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  85. data/lib/active_record/connection_handling.rb +98 -0
  86. data/lib/active_record/core.rb +463 -0
  87. data/lib/active_record/counter_cache.rb +108 -101
  88. data/lib/active_record/dynamic_matchers.rb +131 -0
  89. data/lib/active_record/errors.rb +54 -13
  90. data/lib/active_record/explain.rb +38 -0
  91. data/lib/active_record/explain_registry.rb +30 -0
  92. data/lib/active_record/explain_subscriber.rb +29 -0
  93. data/lib/active_record/fixture_set/file.rb +55 -0
  94. data/lib/active_record/fixtures.rb +703 -785
  95. data/lib/active_record/inheritance.rb +200 -0
  96. data/lib/active_record/integration.rb +60 -0
  97. data/lib/active_record/locale/en.yml +8 -1
  98. data/lib/active_record/locking/optimistic.rb +69 -60
  99. data/lib/active_record/locking/pessimistic.rb +34 -12
  100. data/lib/active_record/log_subscriber.rb +40 -6
  101. data/lib/active_record/migration/command_recorder.rb +164 -0
  102. data/lib/active_record/migration/join_table.rb +15 -0
  103. data/lib/active_record/migration.rb +614 -216
  104. data/lib/active_record/model_schema.rb +345 -0
  105. data/lib/active_record/nested_attributes.rb +248 -119
  106. data/lib/active_record/null_relation.rb +65 -0
  107. data/lib/active_record/persistence.rb +275 -57
  108. data/lib/active_record/query_cache.rb +29 -9
  109. data/lib/active_record/querying.rb +62 -0
  110. data/lib/active_record/railtie.rb +135 -21
  111. data/lib/active_record/railties/console_sandbox.rb +5 -0
  112. data/lib/active_record/railties/controller_runtime.rb +17 -5
  113. data/lib/active_record/railties/databases.rake +249 -359
  114. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  115. data/lib/active_record/readonly_attributes.rb +30 -0
  116. data/lib/active_record/reflection.rb +283 -103
  117. data/lib/active_record/relation/batches.rb +38 -34
  118. data/lib/active_record/relation/calculations.rb +252 -139
  119. data/lib/active_record/relation/delegation.rb +125 -0
  120. data/lib/active_record/relation/finder_methods.rb +182 -188
  121. data/lib/active_record/relation/merger.rb +161 -0
  122. data/lib/active_record/relation/predicate_builder.rb +86 -21
  123. data/lib/active_record/relation/query_methods.rb +917 -134
  124. data/lib/active_record/relation/spawn_methods.rb +53 -92
  125. data/lib/active_record/relation.rb +405 -143
  126. data/lib/active_record/result.rb +67 -0
  127. data/lib/active_record/runtime_registry.rb +17 -0
  128. data/lib/active_record/sanitization.rb +168 -0
  129. data/lib/active_record/schema.rb +20 -14
  130. data/lib/active_record/schema_dumper.rb +55 -46
  131. data/lib/active_record/schema_migration.rb +39 -0
  132. data/lib/active_record/scoping/default.rb +146 -0
  133. data/lib/active_record/scoping/named.rb +175 -0
  134. data/lib/active_record/scoping.rb +82 -0
  135. data/lib/active_record/serialization.rb +8 -46
  136. data/lib/active_record/serializers/xml_serializer.rb +21 -68
  137. data/lib/active_record/statement_cache.rb +26 -0
  138. data/lib/active_record/store.rb +156 -0
  139. data/lib/active_record/tasks/database_tasks.rb +203 -0
  140. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  141. data/lib/active_record/tasks/mysql_database_tasks.rb +143 -0
  142. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  143. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  144. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  145. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  146. data/lib/active_record/test_case.rb +57 -28
  147. data/lib/active_record/timestamp.rb +49 -18
  148. data/lib/active_record/transactions.rb +106 -63
  149. data/lib/active_record/translation.rb +22 -0
  150. data/lib/active_record/validations/associated.rb +25 -24
  151. data/lib/active_record/validations/presence.rb +65 -0
  152. data/lib/active_record/validations/uniqueness.rb +123 -83
  153. data/lib/active_record/validations.rb +29 -29
  154. data/lib/active_record/version.rb +7 -5
  155. data/lib/active_record.rb +83 -34
  156. data/lib/rails/generators/active_record/migration/migration_generator.rb +46 -9
  157. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +19 -0
  158. data/lib/rails/generators/active_record/migration/templates/migration.rb +30 -8
  159. data/lib/rails/generators/active_record/model/model_generator.rb +15 -5
  160. data/lib/rails/generators/active_record/model/templates/model.rb +7 -2
  161. data/lib/rails/generators/active_record/model/templates/module.rb +3 -1
  162. data/lib/rails/generators/active_record.rb +4 -8
  163. metadata +163 -121
  164. data/CHANGELOG +0 -6023
  165. data/examples/associations.png +0 -0
  166. data/lib/active_record/association_preload.rb +0 -403
  167. data/lib/active_record/associations/association_collection.rb +0 -562
  168. data/lib/active_record/associations/association_proxy.rb +0 -295
  169. data/lib/active_record/associations/through_association_scope.rb +0 -154
  170. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -113
  171. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -401
  172. data/lib/active_record/dynamic_finder_match.rb +0 -53
  173. data/lib/active_record/dynamic_scope_match.rb +0 -32
  174. data/lib/active_record/named_scope.rb +0 -138
  175. data/lib/active_record/observer.rb +0 -140
  176. data/lib/active_record/session_store.rb +0 -340
  177. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -16
  178. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  179. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -2
  180. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -24
  181. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -16
@@ -1,112 +1,73 @@
1
- require 'active_support/core_ext/object/blank'
1
+ require 'active_support/core_ext/hash/except'
2
+ require 'active_support/core_ext/hash/slice'
3
+ require 'active_record/relation/merger'
2
4
 
3
5
  module ActiveRecord
4
6
  module SpawnMethods
5
- def merge(r)
6
- merged_relation = clone
7
- return merged_relation unless r
8
7
 
9
- ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) - [:joins, :where]).each do |method|
10
- value = r.send(:"#{method}_values")
11
- unless value.empty?
12
- if method == :includes
13
- merged_relation = merged_relation.includes(value)
14
- else
15
- merged_relation.send(:"#{method}_values=", value)
16
- end
17
- end
18
- end
19
-
20
- merged_relation = merged_relation.joins(r.joins_values)
21
-
22
- merged_wheres = @where_values
23
-
24
- r.where_values.each do |w|
25
- if w.respond_to?(:operator) && w.operator == :==
26
- merged_wheres = merged_wheres.reject { |p|
27
- p.respond_to?(:operator) && p.operator == :== && p.operand1.name == w.operand1.name
28
- }
29
- end
8
+ # This is overridden by Associations::CollectionProxy
9
+ def spawn #:nodoc:
10
+ clone
11
+ end
30
12
 
31
- merged_wheres += [w]
13
+ # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an <tt>ActiveRecord::Relation</tt>.
14
+ # Returns an array representing the intersection of the resulting records with <tt>other</tt>, if <tt>other</tt> is an array.
15
+ # Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
16
+ # # Performs a single join query with both where conditions.
17
+ #
18
+ # recent_posts = Post.order('created_at DESC').first(5)
19
+ # Post.where(published: true).merge(recent_posts)
20
+ # # Returns the intersection of all published posts with the 5 most recently created posts.
21
+ # # (This is just an example. You'd probably want to do this with a single query!)
22
+ #
23
+ # Procs will be evaluated by merge:
24
+ #
25
+ # Post.where(published: true).merge(-> { joins(:comments) })
26
+ # # => Post.where(published: true).joins(:comments)
27
+ #
28
+ # This is mainly intended for sharing common conditions between multiple associations.
29
+ def merge(other)
30
+ if other.is_a?(Array)
31
+ to_a & other
32
+ elsif other
33
+ spawn.merge!(other)
34
+ else
35
+ self
32
36
  end
37
+ end
33
38
 
34
- merged_relation.where_values = merged_wheres
35
-
36
- Relation::SINGLE_VALUE_METHODS.reject {|m| m == :lock}.each do |method|
37
- unless (value = r.send(:"#{method}_value")).nil?
38
- merged_relation.send(:"#{method}_value=", value)
39
- end
39
+ def merge!(other) # :nodoc:
40
+ if !other.is_a?(Relation) && other.respond_to?(:to_proc)
41
+ instance_exec(&other)
42
+ else
43
+ klass = other.is_a?(Hash) ? Relation::HashMerger : Relation::Merger
44
+ klass.new(self, other).merge
40
45
  end
41
-
42
- merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
43
-
44
- # Apply scope extension modules
45
- merged_relation.send :apply_modules, r.extensions
46
-
47
- merged_relation
48
46
  end
49
47
 
50
- alias :& :merge
51
-
48
+ # Removes from the query the condition(s) specified in +skips+.
49
+ #
50
+ # Post.order('id asc').except(:order) # discards the order condition
51
+ # Post.where('id > 10').order('id asc').except(:where) # discards the where condition but keeps the order
52
52
  def except(*skips)
53
- result = self.class.new(@klass, table)
54
-
55
- (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).each do |method|
56
- result.send(:"#{method}_values=", send(:"#{method}_values")) unless skips.include?(method)
57
- end
58
-
59
- Relation::SINGLE_VALUE_METHODS.each do |method|
60
- result.send(:"#{method}_value=", send(:"#{method}_value")) unless skips.include?(method)
61
- end
62
-
63
- result
53
+ relation_with values.except(*skips)
64
54
  end
65
55
 
56
+ # Removes any condition from the query other than the one(s) specified in +onlies+.
57
+ #
58
+ # Post.order('id asc').only(:where) # discards the order condition
59
+ # Post.order('id asc').only(:where, :order) # uses the specified order
66
60
  def only(*onlies)
67
- result = self.class.new(@klass, table)
68
-
69
- onlies.each do |only|
70
- if (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).include?(only)
71
- result.send(:"#{only}_values=", send(:"#{only}_values"))
72
- elsif Relation::SINGLE_VALUE_METHODS.include?(only)
73
- result.send(:"#{only}_value=", send(:"#{only}_value"))
74
- else
75
- raise "Invalid argument : #{only}"
76
- end
77
- end
78
-
79
- result
61
+ relation_with values.slice(*onlies)
80
62
  end
81
63
 
82
- VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset, :extend,
83
- :order, :select, :readonly, :group, :having, :from, :lock ]
84
-
85
- def apply_finder_options(options)
86
- relation = clone
87
- return relation unless options
88
-
89
- options.assert_valid_keys(VALID_FIND_OPTIONS)
64
+ private
90
65
 
91
- [:joins, :select, :group, :having, :limit, :offset, :from, :lock].each do |finder|
92
- if value = options[finder]
93
- relation = relation.send(finder, value)
94
- end
66
+ def relation_with(values) # :nodoc:
67
+ result = Relation.new(klass, table, values)
68
+ result.default_scoped = default_scoped
69
+ result.extend(*extending_values) if extending_values.any?
70
+ result
95
71
  end
96
-
97
- relation = relation.readonly(options[:readonly]) if options.key? :readonly
98
-
99
- # Give precedence to newly-applied orders and groups to play nicely with with_scope
100
- [:group, :order].each do |finder|
101
- relation.send("#{finder}_values=", Array.wrap(options[finder]) + relation.send("#{finder}_values")) if options.has_key?(finder)
102
- end
103
-
104
- relation = relation.where(options[:conditions]) if options.has_key?(:conditions)
105
- relation = relation.includes(options[:include]) if options.has_key?(:include)
106
- relation = relation.extending(options[:extend]) if options.has_key?(:extend)
107
-
108
- relation
109
- end
110
-
111
72
  end
112
73
  end