activerecord 3.1.0.rc4 → 3.1.0.rc5

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 (44) hide show
  1. data/CHANGELOG +25 -0
  2. data/lib/active_record/associations.rb +6 -5
  3. data/lib/active_record/associations/alias_tracker.rb +12 -24
  4. data/lib/active_record/associations/association.rb +56 -6
  5. data/lib/active_record/associations/belongs_to_association.rb +1 -1
  6. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +10 -12
  7. data/lib/active_record/associations/collection_association.rb +44 -31
  8. data/lib/active_record/associations/collection_proxy.rb +11 -4
  9. data/lib/active_record/associations/has_one_association.rb +1 -1
  10. data/lib/active_record/associations/join_helper.rb +1 -2
  11. data/lib/active_record/associations/preloader/association.rb +3 -2
  12. data/lib/active_record/associations/singular_association.rb +12 -4
  13. data/lib/active_record/attribute_methods.rb +1 -1
  14. data/lib/active_record/attribute_methods/primary_key.rb +1 -1
  15. data/lib/active_record/attribute_methods/read.rb +3 -2
  16. data/lib/active_record/autosave_association.rb +1 -1
  17. data/lib/active_record/base.rb +78 -30
  18. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +18 -0
  19. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +6 -6
  20. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +4 -4
  21. data/lib/active_record/connection_adapters/column.rb +2 -0
  22. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -1
  23. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -1
  24. data/lib/active_record/connection_adapters/sqlite_adapter.rb +5 -0
  25. data/lib/active_record/locking/optimistic.rb +1 -1
  26. data/lib/active_record/migration.rb +6 -2
  27. data/lib/active_record/migration/command_recorder.rb +1 -1
  28. data/lib/active_record/named_scope.rb +19 -0
  29. data/lib/active_record/nested_attributes.rb +18 -12
  30. data/lib/active_record/persistence.rb +8 -3
  31. data/lib/active_record/query_cache.rb +8 -0
  32. data/lib/active_record/railtie.rb +23 -0
  33. data/lib/active_record/railties/databases.rake +18 -13
  34. data/lib/active_record/reflection.rb +26 -26
  35. data/lib/active_record/relation.rb +20 -12
  36. data/lib/active_record/relation/batches.rb +0 -2
  37. data/lib/active_record/relation/calculations.rb +11 -5
  38. data/lib/active_record/relation/finder_methods.rb +1 -1
  39. data/lib/active_record/relation/query_methods.rb +16 -7
  40. data/lib/active_record/relation/spawn_methods.rb +1 -1
  41. data/lib/active_record/session_store.rb +19 -9
  42. data/lib/active_record/test_case.rb +0 -1
  43. data/lib/active_record/version.rb +1 -1
  44. metadata +15 -29
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/object/blank'
2
+ require 'active_support/core_ext/module/delegation'
2
3
 
3
4
  module ActiveRecord
4
5
  # = Active Record Relation
@@ -6,7 +7,7 @@ module ActiveRecord
6
7
  JoinOperation = Struct.new(:relation, :join_class, :on)
7
8
  ASSOCIATION_METHODS = [:includes, :eager_load, :preload]
8
9
  MULTI_VALUE_METHODS = [:select, :group, :order, :joins, :where, :having, :bind]
9
- SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :create_with, :from, :reorder, :reverse_order]
10
+ SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reorder, :reverse_order]
10
11
 
11
12
  include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches
12
13
 
@@ -29,6 +30,7 @@ module ActiveRecord
29
30
  SINGLE_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_value", nil)}
30
31
  (ASSOCIATION_METHODS + MULTI_VALUE_METHODS).each {|v| instance_variable_set(:"@#{v}_values", [])}
31
32
  @extensions = []
33
+ @create_with_value = {}
32
34
  end
33
35
 
34
36
  def insert(values)
@@ -214,17 +216,13 @@ module ActiveRecord
214
216
  if conditions || options.present?
215
217
  where(conditions).apply_finder_options(options.slice(:limit, :order)).update_all(updates)
216
218
  else
217
- limit = nil
218
- order = []
219
- # Apply limit and order only if they're both present
220
- if @limit_value.present? == @order_values.present?
221
- limit = arel.limit
222
- order = arel.orders
219
+ stmt = arel.compile_update(Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates)))
220
+
221
+ if limit = arel.limit
222
+ stmt.take limit
223
223
  end
224
224
 
225
- stmt = arel.compile_update(Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates)))
226
- stmt.take limit if limit
227
- stmt.order(*order)
225
+ stmt.order(*arel.orders)
228
226
  stmt.key = table[primary_key]
229
227
  @klass.connection.update stmt.to_sql, 'SQL', bind_values
230
228
  end
@@ -403,11 +401,21 @@ module ActiveRecord
403
401
  end
404
402
 
405
403
  def scope_for_create
406
- @scope_for_create ||= where_values_hash.merge(@create_with_value || {})
404
+ @scope_for_create ||= where_values_hash.merge(create_with_value)
407
405
  end
408
406
 
409
407
  def eager_loading?
410
- @should_eager_load ||= (@eager_load_values.any? || (@includes_values.any? && references_eager_loaded_tables?))
408
+ @should_eager_load ||=
409
+ @eager_load_values.any? ||
410
+ @includes_values.any? && (joined_includes_values.any? || references_eager_loaded_tables?)
411
+ end
412
+
413
+ # Joins that are also marked for preloading. In which case we should just eager load them.
414
+ # Note that this is a naive implementation because we could have strings and symbols which
415
+ # represent the same association, but that aren't matched by this. Also, we could have
416
+ # nested hashes which partially match, e.g. { :a => :b } & { :a => [:b, :c] }
417
+ def joined_includes_values
418
+ @includes_values & @joins_values
411
419
  end
412
420
 
413
421
  def ==(other)
@@ -20,8 +20,6 @@ module ActiveRecord
20
20
  find_in_batches(options) do |records|
21
21
  records.each { |record| yield record }
22
22
  end
23
-
24
- self
25
23
  end
26
24
 
27
25
  # Yields each batch of records that was found by the find +options+ as
@@ -146,10 +146,16 @@ module ActiveRecord
146
146
  if options.except(:distinct).present?
147
147
  apply_finder_options(options.except(:distinct)).calculate(operation, column_name, :distinct => options[:distinct])
148
148
  else
149
- if eager_loading? || (includes_values.present? && references_eager_loaded_tables?)
150
- construct_relation_for_association_calculations.calculate(operation, column_name, options)
149
+ relation = with_default_scope
150
+
151
+ if relation.equal?(self)
152
+ if eager_loading? || (includes_values.present? && references_eager_loaded_tables?)
153
+ construct_relation_for_association_calculations.calculate(operation, column_name, options)
154
+ else
155
+ perform_calculation(operation, column_name, options)
156
+ end
151
157
  else
152
- perform_calculation(operation, column_name, options)
158
+ relation.calculate(operation, column_name, options)
153
159
  end
154
160
  end
155
161
  rescue ThrowResult
@@ -196,7 +202,7 @@ module ActiveRecord
196
202
 
197
203
  def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
198
204
  # Postgresql doesn't like ORDER BY when there are no GROUP BY
199
- relation = with_default_scope.reorder(nil)
205
+ relation = reorder(nil)
200
206
 
201
207
  if operation == "count" && (relation.limit_value || relation.offset_value)
202
208
  # Shortcut when limit is zero.
@@ -245,7 +251,7 @@ module ActiveRecord
245
251
  "#{field} AS #{aliaz}"
246
252
  }
247
253
 
248
- relation = with_default_scope.except(:group).group(group.join(','))
254
+ relation = except(:group).group(group.join(','))
249
255
  relation.select_values = select_values
250
256
 
251
257
  calculated_data = @klass.connection.select_all(relation.to_sql)
@@ -243,7 +243,7 @@ module ActiveRecord
243
243
  end
244
244
 
245
245
  def construct_limited_ids_condition(relation)
246
- orders = relation.order_values
246
+ orders = relation.order_values.map { |val| val.presence }.compact
247
247
  values = @klass.connection.distinct("#{@klass.connection.quote_table_name table_name}.#{primary_key}", orders)
248
248
 
249
249
  relation = relation.dup
@@ -96,11 +96,11 @@ module ActiveRecord
96
96
  relation
97
97
  end
98
98
 
99
- def having(*args)
100
- return self if args.blank?
99
+ def having(opts, *rest)
100
+ return self if opts.blank?
101
101
 
102
102
  relation = clone
103
- relation.having_values += build_where(*args)
103
+ relation.having_values += build_where(opts, rest)
104
104
  relation
105
105
  end
106
106
 
@@ -137,7 +137,7 @@ module ActiveRecord
137
137
 
138
138
  def create_with(value)
139
139
  relation = clone
140
- relation.create_with_value = value && (@create_with_value || {}).merge(value)
140
+ relation.create_with_value = value ? create_with_value.merge(value) : {}
141
141
  relation
142
142
  end
143
143
 
@@ -305,9 +305,18 @@ module ActiveRecord
305
305
  def reverse_sql_order(order_query)
306
306
  order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty?
307
307
 
308
- order_query.join(', ').split(',').collect do |s|
309
- s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
310
- end
308
+ order_query.map do |o|
309
+ case o
310
+ when Arel::Nodes::Ascending, Arel::Nodes::Descending
311
+ o.reverse
312
+ when String, Symbol
313
+ o.to_s.split(',').collect do |s|
314
+ s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
315
+ end
316
+ else
317
+ o
318
+ end
319
+ end.flatten
311
320
  end
312
321
 
313
322
  def array_of_strings?(o)
@@ -55,7 +55,7 @@ module ActiveRecord
55
55
 
56
56
  merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
57
57
 
58
- merged_relation = merged_relation.create_with(r.create_with_value) if r.create_with_value
58
+ merged_relation = merged_relation.create_with(r.create_with_value) unless r.create_with_value.empty?
59
59
 
60
60
  # Apply scope extension modules
61
61
  merged_relation.send :apply_modules, r.extensions
@@ -181,11 +181,6 @@ module ActiveRecord
181
181
  class SqlBypass
182
182
  extend ClassMethods
183
183
 
184
- ##
185
- # :singleton-method:
186
- # Use the ActiveRecord::Base.connection by default.
187
- cattr_accessor :connection
188
-
189
184
  ##
190
185
  # :singleton-method:
191
186
  # The table name defaults to 'sessions'.
@@ -206,10 +201,19 @@ module ActiveRecord
206
201
 
207
202
  class << self
208
203
  alias :data_column_name :data_column
204
+
205
+ # Use the ActiveRecord::Base.connection by default.
206
+ attr_writer :connection
207
+
208
+ # Use the ActiveRecord::Base.connection_pool by default.
209
+ attr_writer :connection_pool
209
210
 
210
- remove_method :connection
211
211
  def connection
212
- @@connection ||= ActiveRecord::Base.connection
212
+ @connection ||= ActiveRecord::Base.connection
213
+ end
214
+
215
+ def connection_pool
216
+ @connection_pool ||= ActiveRecord::Base.connection_pool
213
217
  end
214
218
 
215
219
  # Look up a session by id and unmarshal its data if found.
@@ -219,6 +223,8 @@ module ActiveRecord
219
223
  end
220
224
  end
221
225
  end
226
+
227
+ delegate :connection, :connection=, :connection_pool, :connection_pool=, :to => self
222
228
 
223
229
  attr_reader :session_id, :new_record
224
230
  alias :new_record? :new_record
@@ -297,8 +303,12 @@ module ActiveRecord
297
303
  private
298
304
  def get_session(env, sid)
299
305
  Base.silence do
300
- sid ||= generate_sid
301
- session = find_session(sid)
306
+ unless sid and session = @@session_class.find_by_session_id(sid)
307
+ # If the sid was nil or if there is no pre-existing session under the sid,
308
+ # force the generation of a new sid and associate a new session associated with the new sid
309
+ sid = generate_sid
310
+ session = @@session_class.new(:session_id => sid, :data => {})
311
+ end
302
312
  env[SESSION_RECORD_KEY] = session
303
313
  [sid, session.data]
304
314
  end
@@ -46,7 +46,6 @@ module ActiveRecord
46
46
  $queries_executed = []
47
47
  yield
48
48
  ensure
49
- %w{ BEGIN COMMIT }.each { |x| $queries_executed.delete(x) }
50
49
  assert_equal num, $queries_executed.size, "#{$queries_executed.size} instead of #{num} queries were executed.#{$queries_executed.size == 0 ? '' : "\nQueries:\n#{$queries_executed.join("\n")}"}"
51
50
  end
52
51
 
@@ -3,7 +3,7 @@ module ActiveRecord
3
3
  MAJOR = 3
4
4
  MINOR = 1
5
5
  TINY = 0
6
- PRE = "rc4"
6
+ PRE = "rc5"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
  end
metadata CHANGED
@@ -1,15 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15424109
5
- prerelease: 6
4
+ prerelease: true
6
5
  segments:
7
6
  - 3
8
7
  - 1
9
8
  - 0
10
- - rc
11
- - 4
12
- version: 3.1.0.rc4
9
+ - rc5
10
+ version: 3.1.0.rc5
13
11
  platform: ruby
14
12
  authors:
15
13
  - David Heinemeier Hansson
@@ -17,74 +15,65 @@ autorequire:
17
15
  bindir: bin
18
16
  cert_chain: []
19
17
 
20
- date: 2011-06-09 00:00:00 Z
18
+ date: 2011-07-25 00:00:00 -07:00
19
+ default_executable:
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
23
22
  name: activesupport
24
23
  prerelease: false
25
24
  requirement: &id001 !ruby/object:Gem::Requirement
26
- none: false
27
25
  requirements:
28
26
  - - "="
29
27
  - !ruby/object:Gem::Version
30
- hash: 15424109
31
28
  segments:
32
29
  - 3
33
30
  - 1
34
31
  - 0
35
- - rc
36
- - 4
37
- version: 3.1.0.rc4
32
+ - rc5
33
+ version: 3.1.0.rc5
38
34
  type: :runtime
39
35
  version_requirements: *id001
40
36
  - !ruby/object:Gem::Dependency
41
37
  name: activemodel
42
38
  prerelease: false
43
39
  requirement: &id002 !ruby/object:Gem::Requirement
44
- none: false
45
40
  requirements:
46
41
  - - "="
47
42
  - !ruby/object:Gem::Version
48
- hash: 15424109
49
43
  segments:
50
44
  - 3
51
45
  - 1
52
46
  - 0
53
- - rc
54
- - 4
55
- version: 3.1.0.rc4
47
+ - rc5
48
+ version: 3.1.0.rc5
56
49
  type: :runtime
57
50
  version_requirements: *id002
58
51
  - !ruby/object:Gem::Dependency
59
52
  name: arel
60
53
  prerelease: false
61
54
  requirement: &id003 !ruby/object:Gem::Requirement
62
- none: false
63
55
  requirements:
64
56
  - - ~>
65
57
  - !ruby/object:Gem::Version
66
- hash: 9
67
58
  segments:
68
59
  - 2
69
60
  - 1
70
- - 1
71
- version: 2.1.1
61
+ - 4
62
+ version: 2.1.4
72
63
  type: :runtime
73
64
  version_requirements: *id003
74
65
  - !ruby/object:Gem::Dependency
75
66
  name: tzinfo
76
67
  prerelease: false
77
68
  requirement: &id004 !ruby/object:Gem::Requirement
78
- none: false
79
69
  requirements:
80
70
  - - ~>
81
71
  - !ruby/object:Gem::Version
82
- hash: 37
83
72
  segments:
84
73
  - 0
85
74
  - 3
86
- - 27
87
- version: 0.3.27
75
+ - 29
76
+ version: 0.3.29
88
77
  type: :runtime
89
78
  version_requirements: *id004
90
79
  description: Databases on Rails. Build a persistent domain model by mapping database tables to Ruby classes. Strong conventions for associations, validations, aggregations, migrations, and testing come baked-in.
@@ -223,6 +212,7 @@ files:
223
212
  - lib/rails/generators/active_record/session_migration/session_migration_generator.rb
224
213
  - lib/rails/generators/active_record/session_migration/templates/migration.rb
225
214
  - lib/rails/generators/active_record.rb
215
+ has_rdoc: true
226
216
  homepage: http://www.rubyonrails.org
227
217
  licenses: []
228
218
 
@@ -233,22 +223,18 @@ rdoc_options:
233
223
  require_paths:
234
224
  - lib
235
225
  required_ruby_version: !ruby/object:Gem::Requirement
236
- none: false
237
226
  requirements:
238
227
  - - ">="
239
228
  - !ruby/object:Gem::Version
240
- hash: 57
241
229
  segments:
242
230
  - 1
243
231
  - 8
244
232
  - 7
245
233
  version: 1.8.7
246
234
  required_rubygems_version: !ruby/object:Gem::Requirement
247
- none: false
248
235
  requirements:
249
236
  - - ">"
250
237
  - !ruby/object:Gem::Version
251
- hash: 25
252
238
  segments:
253
239
  - 1
254
240
  - 3
@@ -257,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
257
243
  requirements: []
258
244
 
259
245
  rubyforge_project:
260
- rubygems_version: 1.8.2
246
+ rubygems_version: 1.3.6
261
247
  signing_key:
262
248
  specification_version: 3
263
249
  summary: Object-relational mapper framework (part of Rails).