activerecord 3.1.12 → 3.2.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 (99) hide show
  1. data/CHANGELOG.md +6263 -103
  2. data/README.rdoc +2 -2
  3. data/examples/performance.rb +55 -31
  4. data/lib/active_record.rb +28 -2
  5. data/lib/active_record/aggregations.rb +2 -2
  6. data/lib/active_record/associations.rb +82 -69
  7. data/lib/active_record/associations/association.rb +2 -37
  8. data/lib/active_record/associations/association_scope.rb +3 -30
  9. data/lib/active_record/associations/builder/association.rb +6 -4
  10. data/lib/active_record/associations/builder/belongs_to.rb +3 -3
  11. data/lib/active_record/associations/builder/collection_association.rb +2 -2
  12. data/lib/active_record/associations/builder/has_many.rb +4 -4
  13. data/lib/active_record/associations/builder/has_one.rb +5 -6
  14. data/lib/active_record/associations/builder/singular_association.rb +3 -16
  15. data/lib/active_record/associations/collection_association.rb +55 -28
  16. data/lib/active_record/associations/collection_proxy.rb +1 -35
  17. data/lib/active_record/associations/has_many_association.rb +5 -1
  18. data/lib/active_record/associations/has_many_through_association.rb +11 -8
  19. data/lib/active_record/associations/join_dependency.rb +1 -1
  20. data/lib/active_record/associations/preloader/association.rb +3 -1
  21. data/lib/active_record/attribute_assignment.rb +221 -0
  22. data/lib/active_record/attribute_methods.rb +212 -32
  23. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
  24. data/lib/active_record/attribute_methods/dirty.rb +3 -3
  25. data/lib/active_record/attribute_methods/primary_key.rb +62 -25
  26. data/lib/active_record/attribute_methods/read.rb +69 -80
  27. data/lib/active_record/attribute_methods/serialization.rb +89 -0
  28. data/lib/active_record/attribute_methods/time_zone_conversion.rb +9 -14
  29. data/lib/active_record/attribute_methods/write.rb +27 -5
  30. data/lib/active_record/autosave_association.rb +23 -8
  31. data/lib/active_record/base.rb +223 -1712
  32. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +98 -132
  33. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +82 -29
  34. data/lib/active_record/connection_adapters/abstract/database_statements.rb +13 -42
  35. data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
  36. data/lib/active_record/connection_adapters/abstract/quoting.rb +7 -4
  37. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +36 -25
  38. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +41 -13
  39. data/lib/active_record/connection_adapters/abstract_adapter.rb +78 -43
  40. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +653 -0
  41. data/lib/active_record/connection_adapters/mysql2_adapter.rb +138 -578
  42. data/lib/active_record/connection_adapters/mysql_adapter.rb +86 -658
  43. data/lib/active_record/connection_adapters/postgresql_adapter.rb +144 -94
  44. data/lib/active_record/connection_adapters/schema_cache.rb +50 -0
  45. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -6
  46. data/lib/active_record/connection_adapters/sqlite_adapter.rb +43 -22
  47. data/lib/active_record/counter_cache.rb +1 -1
  48. data/lib/active_record/dynamic_matchers.rb +79 -0
  49. data/lib/active_record/errors.rb +11 -1
  50. data/lib/active_record/explain.rb +83 -0
  51. data/lib/active_record/explain_subscriber.rb +21 -0
  52. data/lib/active_record/fixtures.rb +31 -76
  53. data/lib/active_record/fixtures/file.rb +65 -0
  54. data/lib/active_record/identity_map.rb +1 -7
  55. data/lib/active_record/inheritance.rb +167 -0
  56. data/lib/active_record/integration.rb +49 -0
  57. data/lib/active_record/locking/optimistic.rb +19 -11
  58. data/lib/active_record/locking/pessimistic.rb +1 -1
  59. data/lib/active_record/log_subscriber.rb +3 -3
  60. data/lib/active_record/migration.rb +38 -29
  61. data/lib/active_record/migration/command_recorder.rb +7 -7
  62. data/lib/active_record/model_schema.rb +362 -0
  63. data/lib/active_record/nested_attributes.rb +3 -2
  64. data/lib/active_record/persistence.rb +51 -1
  65. data/lib/active_record/querying.rb +58 -0
  66. data/lib/active_record/railtie.rb +24 -28
  67. data/lib/active_record/railties/controller_runtime.rb +3 -1
  68. data/lib/active_record/railties/databases.rake +133 -77
  69. data/lib/active_record/readonly_attributes.rb +26 -0
  70. data/lib/active_record/reflection.rb +7 -15
  71. data/lib/active_record/relation.rb +78 -35
  72. data/lib/active_record/relation/batches.rb +5 -2
  73. data/lib/active_record/relation/calculations.rb +27 -6
  74. data/lib/active_record/relation/delegation.rb +49 -0
  75. data/lib/active_record/relation/finder_methods.rb +5 -4
  76. data/lib/active_record/relation/predicate_builder.rb +13 -16
  77. data/lib/active_record/relation/query_methods.rb +59 -4
  78. data/lib/active_record/result.rb +1 -1
  79. data/lib/active_record/sanitization.rb +194 -0
  80. data/lib/active_record/schema_dumper.rb +5 -2
  81. data/lib/active_record/scoping.rb +152 -0
  82. data/lib/active_record/scoping/default.rb +140 -0
  83. data/lib/active_record/scoping/named.rb +202 -0
  84. data/lib/active_record/serialization.rb +1 -43
  85. data/lib/active_record/serializers/xml_serializer.rb +2 -44
  86. data/lib/active_record/session_store.rb +11 -11
  87. data/lib/active_record/store.rb +50 -0
  88. data/lib/active_record/test_case.rb +11 -7
  89. data/lib/active_record/timestamp.rb +16 -3
  90. data/lib/active_record/transactions.rb +5 -5
  91. data/lib/active_record/translation.rb +22 -0
  92. data/lib/active_record/validations.rb +1 -1
  93. data/lib/active_record/validations/associated.rb +5 -4
  94. data/lib/active_record/validations/uniqueness.rb +4 -4
  95. data/lib/active_record/version.rb +3 -3
  96. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +1 -5
  97. metadata +48 -38
  98. checksums.yaml +0 -7
  99. data/lib/active_record/named_scope.rb +0 -200
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 39618d1c6a68e5b4619c40b74c4ce99a97c6e316
4
- data.tar.gz: 0aff9db1c8dc331c7f293a7e9a80bfa6343d8d04
5
- SHA512:
6
- metadata.gz: 9960b003f80c2a2abb86ee83e854c763af29fcaeb4eb01f1da4ebc865d945e9b4c30292e8d635275451a1c8fcb3e2ccdc3f6c7e7ece37578bd9a74fc674325e2
7
- data.tar.gz: aaf2fa286f74dd1d9a81f55a0048e6405a50019d67974a4b17d59ed7065ecb380edc8496222ad2e7ed65ccd07756bd44535c1a4feb1e68a076a5656df18847a1
@@ -1,200 +0,0 @@
1
- require 'active_support/core_ext/array'
2
- require 'active_support/core_ext/hash/except'
3
- require 'active_support/core_ext/kernel/singleton_class'
4
- require 'active_support/core_ext/object/blank'
5
- require 'active_support/core_ext/class/attribute'
6
-
7
- module ActiveRecord
8
- # = Active Record Named \Scopes
9
- module NamedScope
10
- extend ActiveSupport::Concern
11
-
12
- module ClassMethods
13
- # Returns an anonymous \scope.
14
- #
15
- # posts = Post.scoped
16
- # posts.size # Fires "select count(*) from posts" and returns the count
17
- # posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
18
- #
19
- # fruits = Fruit.scoped
20
- # fruits = fruits.where(:colour => 'red') if options[:red_only]
21
- # fruits = fruits.limit(10) if limited?
22
- #
23
- # Anonymous \scopes tend to be useful when procedurally generating complex
24
- # queries, where passing intermediate values (\scopes) around as first-class
25
- # objects is convenient.
26
- #
27
- # You can define a \scope that applies to all finders using
28
- # ActiveRecord::Base.default_scope.
29
- def scoped(options = nil)
30
- if options
31
- scoped.apply_finder_options(options)
32
- else
33
- if current_scope
34
- current_scope.clone
35
- else
36
- scope = relation.clone
37
- scope.default_scoped = true
38
- scope
39
- end
40
- end
41
- end
42
-
43
- ##
44
- # Collects attributes from scopes that should be applied when creating
45
- # an AR instance for the particular class this is called on.
46
- def scope_attributes # :nodoc:
47
- if current_scope
48
- current_scope.scope_for_create
49
- else
50
- scope = relation.clone
51
- scope.default_scoped = true
52
- scope.scope_for_create
53
- end
54
- end
55
-
56
- ##
57
- # Are there default attributes associated with this scope?
58
- def scope_attributes? # :nodoc:
59
- current_scope || default_scopes.any?
60
- end
61
-
62
- # Adds a class method for retrieving and querying objects. A \scope represents a narrowing of a database query,
63
- # such as <tt>where(:color => :red).select('shirts.*').includes(:washing_instructions)</tt>.
64
- #
65
- # class Shirt < ActiveRecord::Base
66
- # scope :red, where(:color => 'red')
67
- # scope :dry_clean_only, joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true)
68
- # end
69
- #
70
- # The above calls to <tt>scope</tt> define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red,
71
- # in effect, represents the query <tt>Shirt.where(:color => 'red')</tt>.
72
- #
73
- # Note that this is simply 'syntactic sugar' for defining an actual class method:
74
- #
75
- # class Shirt < ActiveRecord::Base
76
- # def self.red
77
- # where(:color => 'red')
78
- # end
79
- # end
80
- #
81
- # Unlike <tt>Shirt.find(...)</tt>, however, the object returned by Shirt.red is not an Array; it
82
- # resembles the association object constructed by a <tt>has_many</tt> declaration. For instance,
83
- # you can invoke <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>, <tt>Shirt.red.where(:size => 'small')</tt>.
84
- # Also, just as with the association objects, named \scopes act like an Array, implementing Enumerable;
85
- # <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt>
86
- # all behave as if Shirt.red really was an Array.
87
- #
88
- # These named \scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce
89
- # all shirts that are both red and dry clean only.
90
- # Nested finds and calculations also work with these compositions: <tt>Shirt.red.dry_clean_only.count</tt>
91
- # returns the number of garments for which these criteria obtain. Similarly with
92
- # <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
93
- #
94
- # All \scopes are available as class methods on the ActiveRecord::Base descendant upon which
95
- # the \scopes were defined. But they are also available to <tt>has_many</tt> associations. If,
96
- #
97
- # class Person < ActiveRecord::Base
98
- # has_many :shirts
99
- # end
100
- #
101
- # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of Elton's red, dry clean
102
- # only shirts.
103
- #
104
- # Named \scopes can also be procedural:
105
- #
106
- # class Shirt < ActiveRecord::Base
107
- # scope :colored, lambda { |color| where(:color => color) }
108
- # end
109
- #
110
- # In this example, <tt>Shirt.colored('puce')</tt> finds all puce shirts.
111
- #
112
- # On Ruby 1.9 you can use the 'stabby lambda' syntax:
113
- #
114
- # scope :colored, ->(color) { where(:color => color) }
115
- #
116
- # Note that scopes defined with \scope will be evaluated when they are defined, rather than
117
- # when they are used. For example, the following would be incorrect:
118
- #
119
- # class Post < ActiveRecord::Base
120
- # scope :recent, where('published_at >= ?', Time.now - 1.week)
121
- # end
122
- #
123
- # The example above would be 'frozen' to the <tt>Time.now</tt> value when the <tt>Post</tt>
124
- # class was defined, and so the resultant SQL query would always be the same. The correct
125
- # way to do this would be via a lambda, which will re-evaluate the scope each time
126
- # it is called:
127
- #
128
- # class Post < ActiveRecord::Base
129
- # scope :recent, lambda { where('published_at >= ?', Time.now - 1.week) }
130
- # end
131
- #
132
- # Named \scopes can also have extensions, just as with <tt>has_many</tt> declarations:
133
- #
134
- # class Shirt < ActiveRecord::Base
135
- # scope :red, where(:color => 'red') do
136
- # def dom_id
137
- # 'red_shirts'
138
- # end
139
- # end
140
- # end
141
- #
142
- # Scopes can also be used while creating/building a record.
143
- #
144
- # class Article < ActiveRecord::Base
145
- # scope :published, where(:published => true)
146
- # end
147
- #
148
- # Article.published.new.published # => true
149
- # Article.published.create.published # => true
150
- #
151
- # Class methods on your model are automatically available
152
- # on scopes. Assuming the following setup:
153
- #
154
- # class Article < ActiveRecord::Base
155
- # scope :published, where(:published => true)
156
- # scope :featured, where(:featured => true)
157
- #
158
- # def self.latest_article
159
- # order('published_at desc').first
160
- # end
161
- #
162
- # def self.titles
163
- # map(&:title)
164
- # end
165
- #
166
- # end
167
- #
168
- # We are able to call the methods like this:
169
- #
170
- # Article.published.featured.latest_article
171
- # Article.featured.titles
172
-
173
- def scope(name, scope_options = {})
174
- name = name.to_sym
175
- valid_scope_name?(name)
176
- extension = Module.new(&Proc.new) if block_given?
177
-
178
- scope_proc = lambda do |*args|
179
- options = scope_options.respond_to?(:call) ? unscoped { scope_options.call(*args) } : scope_options
180
- options = scoped.apply_finder_options(options) if options.is_a?(Hash)
181
-
182
- relation = scoped.merge(options)
183
-
184
- extension ? relation.extending(extension) : relation
185
- end
186
-
187
- singleton_class.send(:redefine_method, name, &scope_proc)
188
- end
189
-
190
- protected
191
-
192
- def valid_scope_name?(name)
193
- if respond_to?(name, true)
194
- logger.warn "Creating scope :#{name}. " \
195
- "Overwriting existing method #{self.name}.#{name}."
196
- end
197
- end
198
- end
199
- end
200
- end