activerecord 3.0.0 → 3.0.2

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 (46) hide show
  1. data/CHANGELOG +37 -0
  2. data/examples/performance.rb +18 -1
  3. data/lib/active_record.rb +3 -3
  4. data/lib/active_record/aggregations.rb +2 -2
  5. data/lib/active_record/association_preload.rb +1 -1
  6. data/lib/active_record/associations.rb +59 -26
  7. data/lib/active_record/associations/association_collection.rb +28 -18
  8. data/lib/active_record/associations/association_proxy.rb +4 -4
  9. data/lib/active_record/associations/belongs_to_association.rb +3 -3
  10. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +10 -13
  11. data/lib/active_record/associations/has_many_through_association.rb +2 -3
  12. data/lib/active_record/associations/has_one_association.rb +6 -6
  13. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  14. data/lib/active_record/attribute_methods/before_type_cast.rb +1 -4
  15. data/lib/active_record/attribute_methods/primary_key.rb +4 -3
  16. data/lib/active_record/autosave_association.rb +7 -7
  17. data/lib/active_record/base.rb +62 -46
  18. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +6 -8
  19. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +2 -2
  20. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +5 -9
  21. data/lib/active_record/connection_adapters/mysql_adapter.rb +7 -7
  22. data/lib/active_record/connection_adapters/sqlite_adapter.rb +2 -2
  23. data/lib/active_record/dynamic_finder_match.rb +20 -17
  24. data/lib/active_record/dynamic_scope_match.rb +6 -15
  25. data/lib/active_record/fixtures.rb +3 -5
  26. data/lib/active_record/locking/optimistic.rb +1 -1
  27. data/lib/active_record/locking/pessimistic.rb +4 -4
  28. data/lib/active_record/nested_attributes.rb +17 -13
  29. data/lib/active_record/persistence.rb +7 -8
  30. data/lib/active_record/railties/databases.rake +7 -7
  31. data/lib/active_record/relation.rb +16 -18
  32. data/lib/active_record/relation/batches.rb +1 -1
  33. data/lib/active_record/relation/calculations.rb +37 -28
  34. data/lib/active_record/relation/finder_methods.rb +19 -19
  35. data/lib/active_record/relation/predicate_builder.rb +3 -1
  36. data/lib/active_record/relation/query_methods.rb +100 -75
  37. data/lib/active_record/relation/spawn_methods.rb +50 -39
  38. data/lib/active_record/serialization.rb +1 -1
  39. data/lib/active_record/session_store.rb +4 -4
  40. data/lib/active_record/transactions.rb +6 -6
  41. data/lib/active_record/validations.rb +1 -1
  42. data/lib/active_record/validations/uniqueness.rb +6 -1
  43. data/lib/active_record/version.rb +2 -2
  44. data/lib/rails/generators/active_record.rb +2 -10
  45. data/lib/rails/generators/active_record/migration.rb +15 -0
  46. metadata +15 -14
@@ -5,9 +5,11 @@ module ActiveRecord
5
5
  def merge(r)
6
6
  merged_relation = clone
7
7
  return merged_relation unless r
8
+ return to_a & r if r.is_a?(Array)
8
9
 
9
- ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) - [:joins, :where]).each do |method|
10
+ Relation::ASSOCIATION_METHODS.each do |method|
10
11
  value = r.send(:"#{method}_values")
12
+
11
13
  unless value.empty?
12
14
  if method == :includes
13
15
  merged_relation = merged_relation.includes(value)
@@ -17,26 +19,44 @@ module ActiveRecord
17
19
  end
18
20
  end
19
21
 
20
- merged_relation = merged_relation.joins(r.joins_values)
21
-
22
- merged_wheres = @where_values
22
+ (Relation::MULTI_VALUE_METHODS - [:joins, :where, :order]).each do |method|
23
+ value = r.send(:"#{method}_values")
24
+ merged_relation.send(:"#{method}_values=", merged_relation.send(:"#{method}_values") + value) if value.present?
25
+ end
23
26
 
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
- }
27
+ order_value = r.order_values
28
+ if order_value.present?
29
+ if r.reorder_flag
30
+ merged_relation.order_values = order_value
31
+ else
32
+ merged_relation.order_values = merged_relation.order_values + order_value
29
33
  end
34
+ end
30
35
 
31
- merged_wheres += [w]
36
+ merged_relation = merged_relation.joins(r.joins_values)
37
+
38
+ merged_wheres = @where_values + r.where_values
39
+
40
+ unless @where_values.empty?
41
+ # Remove duplicates, last one wins.
42
+ seen = Hash.new { |h,table| h[table] = {} }
43
+ merged_wheres = merged_wheres.reverse.reject { |w|
44
+ nuke = false
45
+ if w.respond_to?(:operator) && w.operator == :==
46
+ name = w.left.name
47
+ table = w.left.relation.name
48
+ nuke = seen[table][name]
49
+ seen[table][name] = true
50
+ end
51
+ nuke
52
+ }.reverse
32
53
  end
33
54
 
34
55
  merged_relation.where_values = merged_wheres
35
56
 
36
57
  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
58
+ value = r.send(:"#{method}_value")
59
+ merged_relation.send(:"#{method}_value=", value) unless value.nil?
40
60
  end
41
61
 
42
62
  merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
@@ -52,12 +72,12 @@ module ActiveRecord
52
72
  def except(*skips)
53
73
  result = self.class.new(@klass, table)
54
74
 
55
- (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).each do |method|
56
- result.send(:"#{method}_values=", send(:"#{method}_values")) unless skips.include?(method)
75
+ ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) - skips).each do |method|
76
+ result.send(:"#{method}_values=", send(:"#{method}_values"))
57
77
  end
58
78
 
59
- Relation::SINGLE_VALUE_METHODS.each do |method|
60
- result.send(:"#{method}_value=", send(:"#{method}_value")) unless skips.include?(method)
79
+ (Relation::SINGLE_VALUE_METHODS - skips).each do |method|
80
+ result.send(:"#{method}_value=", send(:"#{method}_value"))
61
81
  end
62
82
 
63
83
  result
@@ -66,14 +86,12 @@ module ActiveRecord
66
86
  def only(*onlies)
67
87
  result = self.class.new(@klass, table)
68
88
 
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
89
+ ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) & onlies).each do |method|
90
+ result.send(:"#{method}_values=", send(:"#{method}_values"))
91
+ end
92
+
93
+ (Relation::SINGLE_VALUE_METHODS & onlies).each do |method|
94
+ result.send(:"#{method}_value=", send(:"#{method}_value"))
77
95
  end
78
96
 
79
97
  result
@@ -87,23 +105,16 @@ module ActiveRecord
87
105
  return relation unless options
88
106
 
89
107
  options.assert_valid_keys(VALID_FIND_OPTIONS)
108
+ finders = options.dup
109
+ finders.delete_if { |key, value| value.nil? }
90
110
 
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
95
- 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)
111
+ ([:joins, :select, :group, :order, :having, :limit, :offset, :from, :lock, :readonly] & finders.keys).each do |finder|
112
+ relation = relation.send(finder, finders[finder])
102
113
  end
103
114
 
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)
115
+ relation = relation.where(finders[:conditions]) if options.has_key?(:conditions)
116
+ relation = relation.includes(finders[:include]) if options.has_key?(:include)
117
+ relation = relation.extending(finders[:extend]) if options.has_key?(:extend)
107
118
 
108
119
  relation
109
120
  end
@@ -5,7 +5,7 @@ module ActiveRecord #:nodoc:
5
5
  include ActiveModel::Serializers::JSON
6
6
 
7
7
  def serializable_hash(options = nil)
8
- options ||= {}
8
+ options = options.try(:clone) || {}
9
9
 
10
10
  options[:except] = Array.wrap(options[:except]).map { |n| n.to_s }
11
11
  options[:except] |= Array.wrap(self.class.inheritance_column)
@@ -228,7 +228,7 @@ module ActiveRecord
228
228
  @session_id = attributes[:session_id]
229
229
  @data = attributes[:data]
230
230
  @marshaled_data = attributes[:marshaled_data]
231
- @new_record = @marshaled_data.nil?
231
+ @persisted = !@marshaled_data.nil?
232
232
  end
233
233
 
234
234
  # Lazy-unmarshal session state.
@@ -252,8 +252,8 @@ module ActiveRecord
252
252
  marshaled_data = self.class.marshal(data)
253
253
  connect = connection
254
254
 
255
- if @new_record
256
- @new_record = false
255
+ unless @persisted
256
+ @persisted = true
257
257
  connect.update <<-end_sql, 'Create session'
258
258
  INSERT INTO #{table_name} (
259
259
  #{connect.quote_column_name(session_id_column)},
@@ -272,7 +272,7 @@ module ActiveRecord
272
272
  end
273
273
 
274
274
  def destroy
275
- return if @new_record
275
+ return unless @persisted
276
276
 
277
277
  connect = connection
278
278
  connect.delete <<-end_sql, 'Destroy session'
@@ -242,7 +242,7 @@ module ActiveRecord
242
242
  with_transaction_returning_status { super }
243
243
  end
244
244
 
245
- # Reset id and @new_record if the transaction rolls back.
245
+ # Reset id and @persisted if the transaction rolls back.
246
246
  def rollback_active_record_state!
247
247
  remember_transaction_record_state
248
248
  yield
@@ -297,9 +297,9 @@ module ActiveRecord
297
297
  # Save the new record state and id of a record so it can be restored later if a transaction fails.
298
298
  def remember_transaction_record_state #:nodoc
299
299
  @_start_transaction_state ||= {}
300
- unless @_start_transaction_state.include?(:new_record)
300
+ unless @_start_transaction_state.include?(:persisted)
301
301
  @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
302
- @_start_transaction_state[:new_record] = @new_record
302
+ @_start_transaction_state[:persisted] = @persisted
303
303
  end
304
304
  unless @_start_transaction_state.include?(:destroyed)
305
305
  @_start_transaction_state[:destroyed] = @destroyed
@@ -323,7 +323,7 @@ module ActiveRecord
323
323
  restore_state = remove_instance_variable(:@_start_transaction_state)
324
324
  if restore_state
325
325
  @attributes = @attributes.dup if @attributes.frozen?
326
- @new_record = restore_state[:new_record]
326
+ @persisted = restore_state[:persisted]
327
327
  @destroyed = restore_state[:destroyed]
328
328
  if restore_state[:id]
329
329
  self.id = restore_state[:id]
@@ -345,11 +345,11 @@ module ActiveRecord
345
345
  def transaction_include_action?(action) #:nodoc
346
346
  case action
347
347
  when :create
348
- transaction_record_state(:new_record)
348
+ transaction_record_state(:new_record) || !transaction_record_state(:persisted)
349
349
  when :destroy
350
350
  destroyed?
351
351
  when :update
352
- !(transaction_record_state(:new_record) || destroyed?)
352
+ !(transaction_record_state(:new_record) || !transaction_record_state(:persisted) || destroyed?)
353
353
  end
354
354
  end
355
355
  end
@@ -51,7 +51,7 @@ module ActiveRecord
51
51
 
52
52
  # Runs all the specified validations and returns true if no errors were added otherwise false.
53
53
  def valid?(context = nil)
54
- context ||= (new_record? ? :create : :update)
54
+ context ||= (persisted? ? :update : :create)
55
55
  output = super(context)
56
56
 
57
57
  deprecated_callback_method(:validate)
@@ -17,6 +17,11 @@ module ActiveRecord
17
17
  table = finder_class.unscoped
18
18
 
19
19
  table_name = record.class.quoted_table_name
20
+
21
+ if value && record.class.serialized_attributes.key?(attribute.to_s)
22
+ value = YAML.dump value
23
+ end
24
+
20
25
  sql, params = mount_sql_and_params(finder_class, table_name, attribute, value)
21
26
 
22
27
  relation = table.where(sql, *params)
@@ -26,7 +31,7 @@ module ActiveRecord
26
31
  relation = relation.where(scope_item => scope_value)
27
32
  end
28
33
 
29
- unless record.new_record?
34
+ if record.persisted?
30
35
  # TODO : This should be in Arel
31
36
  relation = relation.where("#{record.class.quoted_table_name}.#{record.class.primary_key} <> ?", record.send(:id))
32
37
  end
@@ -2,8 +2,8 @@ module ActiveRecord
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
- TINY = 0
6
-
5
+ TINY = 1
6
+
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
9
9
  end
@@ -1,27 +1,19 @@
1
1
  require 'rails/generators/named_base'
2
2
  require 'rails/generators/migration'
3
3
  require 'rails/generators/active_model'
4
+ require 'rails/generators/active_record/migration'
4
5
  require 'active_record'
5
6
 
6
7
  module ActiveRecord
7
8
  module Generators
8
9
  class Base < Rails::Generators::NamedBase #:nodoc:
9
10
  include Rails::Generators::Migration
11
+ extend ActiveRecord::Generators::Migration
10
12
 
11
13
  # Set the current directory as base for the inherited generators.
12
14
  def self.base_root
13
15
  File.dirname(__FILE__)
14
16
  end
15
-
16
- # Implement the required interface for Rails::Generators::Migration.
17
- def self.next_migration_number(dirname) #:nodoc:
18
- next_migration_number = current_migration_number(dirname) + 1
19
- if ActiveRecord::Base.timestamped_migrations
20
- [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
21
- else
22
- "%.3d" % next_migration_number
23
- end
24
- end
25
17
  end
26
18
  end
27
19
  end
@@ -0,0 +1,15 @@
1
+ module ActiveRecord
2
+ module Generators
3
+ module Migration
4
+ # Implement the required interface for Rails::Generators::Migration.
5
+ def next_migration_number(dirname) #:nodoc:
6
+ next_migration_number = current_migration_number(dirname) + 1
7
+ if ActiveRecord::Base.timestamped_migrations
8
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
9
+ else
10
+ "%.3d" % next_migration_number
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 0
10
- version: 3.0.0
9
+ - 2
10
+ version: 3.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - David Heinemeier Hansson
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-29 00:00:00 -05:00
18
+ date: 2010-11-15 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -26,12 +26,12 @@ dependencies:
26
26
  requirements:
27
27
  - - "="
28
28
  - !ruby/object:Gem::Version
29
- hash: 7
29
+ hash: 3
30
30
  segments:
31
31
  - 3
32
32
  - 0
33
- - 0
34
- version: 3.0.0
33
+ - 2
34
+ version: 3.0.2
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
@@ -42,12 +42,12 @@ dependencies:
42
42
  requirements:
43
43
  - - "="
44
44
  - !ruby/object:Gem::Version
45
- hash: 7
45
+ hash: 3
46
46
  segments:
47
47
  - 3
48
48
  - 0
49
- - 0
50
- version: 3.0.0
49
+ - 2
50
+ version: 3.0.2
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
@@ -58,12 +58,12 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- hash: 23
61
+ hash: 11
62
62
  segments:
63
- - 1
64
- - 0
63
+ - 2
65
64
  - 0
66
- version: 1.0.0
65
+ - 2
66
+ version: 2.0.2
67
67
  type: :runtime
68
68
  version_requirements: *id003
69
69
  - !ruby/object:Gem::Dependency
@@ -174,6 +174,7 @@ files:
174
174
  - lib/active_record.rb
175
175
  - lib/rails/generators/active_record/migration/migration_generator.rb
176
176
  - lib/rails/generators/active_record/migration/templates/migration.rb
177
+ - lib/rails/generators/active_record/migration.rb
177
178
  - lib/rails/generators/active_record/model/model_generator.rb
178
179
  - lib/rails/generators/active_record/model/templates/migration.rb
179
180
  - lib/rails/generators/active_record/model/templates/model.rb