activerecord 4.0.5 → 4.0.6.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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +198 -0
  3. data/lib/active_record/association_relation.rb +4 -0
  4. data/lib/active_record/associations.rb +7 -1
  5. data/lib/active_record/associations/builder/belongs_to.rb +3 -4
  6. data/lib/active_record/associations/collection_association.rb +5 -5
  7. data/lib/active_record/associations/collection_proxy.rb +4 -2
  8. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -1
  9. data/lib/active_record/associations/has_many_association.rb +4 -4
  10. data/lib/active_record/associations/has_many_through_association.rb +5 -1
  11. data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
  12. data/lib/active_record/associations/preloader.rb +6 -27
  13. data/lib/active_record/associations/preloader/association.rb +1 -1
  14. data/lib/active_record/associations/singular_association.rb +3 -3
  15. data/lib/active_record/attribute_methods.rb +1 -0
  16. data/lib/active_record/attribute_methods/dirty.rb +2 -2
  17. data/lib/active_record/attribute_methods/serialization.rb +16 -5
  18. data/lib/active_record/base.rb +1 -1
  19. data/lib/active_record/callbacks.rb +2 -2
  20. data/lib/active_record/connection_adapters/abstract/database_statements.rb +9 -12
  21. data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -0
  22. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
  23. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +6 -0
  24. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +5 -5
  25. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +1 -4
  26. data/lib/active_record/connection_adapters/postgresql/quoting.rb +9 -0
  27. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +10 -5
  28. data/lib/active_record/connection_adapters/postgresql_adapter.rb +7 -0
  29. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +6 -3
  30. data/lib/active_record/connection_handling.rb +2 -2
  31. data/lib/active_record/core.rb +1 -0
  32. data/lib/active_record/locking/optimistic.rb +1 -1
  33. data/lib/active_record/migration.rb +1 -1
  34. data/lib/active_record/null_relation.rb +9 -3
  35. data/lib/active_record/persistence.rb +9 -7
  36. data/lib/active_record/railties/databases.rake +2 -1
  37. data/lib/active_record/reflection.rb +3 -3
  38. data/lib/active_record/relation.rb +4 -2
  39. data/lib/active_record/relation/merger.rb +10 -2
  40. data/lib/active_record/relation/query_methods.rb +2 -2
  41. data/lib/active_record/scoping/default.rb +3 -3
  42. data/lib/active_record/store.rb +16 -4
  43. data/lib/active_record/test_case.rb +6 -0
  44. data/lib/active_record/timestamp.rb +2 -2
  45. data/lib/active_record/transactions.rb +1 -1
  46. data/lib/active_record/version.rb +1 -1
  47. metadata +27 -37
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a0eee7da9c94ef26da56fe60b92893386de6d2b1
4
+ data.tar.gz: 9008c81b96ed86e1c650bbed89290d6c0e1b4802
5
+ SHA512:
6
+ metadata.gz: c697cbcabccdf2e4494c67fc3c86f099686f8316a65d74a5986dbe6a022ec6eb3106b796d7e82722a43f86a4c91afca40e0f47b9e37a03dd4e6427bec0354d4c
7
+ data.tar.gz: 80fefaf272a8bf843e275c25abcdf528a6a6a2518fba10794f842a79bb2a8b675dd62546e736c90fc235ad71df3e00782330b8ca52d2752396010de2d1400cf5
@@ -1,3 +1,201 @@
1
+ ## Rails 4.0.6 (May 27, 2014) ##
2
+
3
+ * Fixed the inferred table name of a has_and_belongs_to_many auxiliar
4
+ table inside a schema.
5
+
6
+ Fixes #14824
7
+
8
+ *Eric Chahin*
9
+
10
+ * Fix bug that added `table_name_prefix` and `table_name_suffix` to
11
+ extension names in PostgreSQL when migrating.
12
+
13
+ *Joao Carlos*
14
+
15
+ * `ActiveRecord::Relation::Merger#filter_binds` now compares equivalent symbols and
16
+ strings in column names as equal.
17
+
18
+ This fixes a rare case in which more bind values are passed than there are
19
+ placeholders for them in the generated SQL statement, which can make PostgreSQL
20
+ throw a `StatementInvalid` exception.
21
+
22
+ *Nat Budin*
23
+
24
+ * Calling `delete_all` on an unloaded `CollectionProxy` no longer
25
+ generates a SQL statement containing each id of the collection:
26
+
27
+ Before:
28
+
29
+ DELETE FROM `model` WHERE `model`.`parent_id` = 1
30
+ AND `model`.`id` IN (1, 2, 3...)
31
+
32
+ After:
33
+
34
+ DELETE FROM `model` WHERE `model`.`parent_id` = 1
35
+
36
+ *Eileen M. Uchitelle*, *Aaron Patterson*
37
+
38
+ * Fix `stored_attributes` to correctly merge the details of stored
39
+ attributes defined in parent classes.
40
+
41
+ Fixes #14672.
42
+
43
+ *Brad Bennett*, *Jessica Yao*, *Lakshmi Parthasarathy*
44
+
45
+ * Fix bug where `ActiveRecord::Store` used a global `Hash` to keep track of
46
+ all registered `stored_attributes`. Now every subclass of
47
+ `ActiveRecord::Base` has it's own `Hash`.
48
+
49
+ *Yves Senn*
50
+
51
+ * `change_column_default` allows `[]` as argument to `change_column_default`.
52
+
53
+ Fixes #11586.
54
+
55
+ *Yves Senn*
56
+
57
+ * Fixed has_and_belongs_to_many's CollectionAssociation size calculation.
58
+
59
+ has_and_belongs_to_many should not include new records as part of
60
+ `#count_records` as new records are already counted.
61
+
62
+ Fixes #14914.
63
+
64
+ *Fred Wu*
65
+
66
+ * Stringify all variables keys of MySQL connection configuration.
67
+
68
+ When `sql_mode` variable for MySQL adapters set in configuration as `String`
69
+ was ignored and overwritten by strict mode option.
70
+
71
+ Fixes #14895.
72
+
73
+ *Paul Nikitochkin*
74
+
75
+ * Ensure SQLite3 statements are closed on errors.
76
+
77
+ Fixes: #13631.
78
+
79
+ *Timur Alperovich*
80
+
81
+ * When joining tables with a default scope, ensure the generated table name
82
+ in the `ON` conditions from the default scope is correctly aliased.
83
+
84
+ Backports #14154.
85
+
86
+ *Matt Jones*
87
+
88
+ * Fix name collision with `Array#select!` with `Relation#select!`.
89
+
90
+ Fixes #14752.
91
+
92
+ *Earl St Sauver*
93
+
94
+ * When a destroyed record is duped, the dup is not `destroyed?`.
95
+
96
+ *Kuldeep Aggarwal*
97
+
98
+ * Fixed has_many association to make it support irregular inflections.
99
+
100
+ Fixes #8928.
101
+
102
+ *arthurnn*, *Javier Goizueta*
103
+
104
+ * Fixed a problem where count used with a grouping was not returning a Hash.
105
+
106
+ Fixes #14721.
107
+
108
+ *Eric Chahin*
109
+
110
+ * Do not quote uuid default value on `change_column`.
111
+
112
+ Fixes #14604.
113
+
114
+ *Eric Chahin*
115
+
116
+ * The comparison between `Relation` and `CollectionProxy` should be consistent.
117
+
118
+ Example:
119
+
120
+ author.posts == Post.where(author_id: author.id)
121
+ # => true
122
+ Post.where(author_id: author.id) == author.posts
123
+ # => true
124
+
125
+ Fixes #13506.
126
+
127
+ *Lauro Caetano*
128
+
129
+ * PostgreSQL adapter only warns once for every missing OID per connection.
130
+
131
+ Fixes #14275.
132
+
133
+ *Matthew Draper*, *Yves Senn*
134
+
135
+ * Fix insertion of records via `has_many :through` association with scope.
136
+
137
+ Fixes #3548.
138
+
139
+ *Ivan Antropov*
140
+
141
+ * Make possible to have an association called `records`.
142
+
143
+ Fixes #11645.
144
+
145
+ *prathamesh-sonpatki*
146
+
147
+ * `to_sql` on an association now matches the query that is actually executed, where it
148
+ could previously have incorrectly accrued additional conditions (e.g. as a result of
149
+ a previous query). `CollectionProxy` now always defers to the association scope's
150
+ `arel` method so the (incorrect) inherited one should be entirely concealed.
151
+
152
+ Fixes #14003.
153
+
154
+ *Jefferson Lai*
155
+
156
+ * Fixed error when using `with_options` with lambda.
157
+
158
+ Fixes #9805.
159
+
160
+ *Lauro Caetano*
161
+
162
+ * Fixed error when specifying a non-empty default value on a PostgreSQL array column.
163
+
164
+ Fixes #10613.
165
+
166
+ *Luke Steensen*
167
+
168
+ * Make possible to change `record_timestamps` inside Callbacks.
169
+
170
+ *Tieg Zaharia*
171
+
172
+ * Fixed error where `#persisted?` throws `SystemStackError` for an unsaved model with a
173
+ custom primary key that didn't save due to validation error.
174
+
175
+ Fixes #14393.
176
+
177
+ *Chris Finne*
178
+
179
+ * `rake db:structure:dump` only dumps schema information if the schema
180
+ migration table exists.
181
+
182
+ Fixes #14217.
183
+
184
+ *Yves Senn*
185
+
186
+ * Fix counter cache when association uses a `class_name`.
187
+
188
+ Fixes #14369.
189
+
190
+ *arthurnn*
191
+
192
+ * Add support for `Relation` be passed as parameter on `QueryCache#select_all`.
193
+
194
+ Fixes #14361.
195
+
196
+ *arthurnn*
197
+
198
+
1
199
  ## Rails 4.0.5 (May 6, 2014) ##
2
200
 
3
201
  *No changes*
@@ -9,6 +9,10 @@ module ActiveRecord
9
9
  @association
10
10
  end
11
11
 
12
+ def ==(other)
13
+ other == to_a
14
+ end
15
+
12
16
  private
13
17
 
14
18
  def exec_queries
@@ -4,6 +4,12 @@ require 'active_support/core_ext/module/remove_method'
4
4
  require 'active_record/errors'
5
5
 
6
6
  module ActiveRecord
7
+ class AssociationNotFoundError < ConfigurationError #:nodoc:
8
+ def initialize(record, association_name)
9
+ super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
10
+ end
11
+ end
12
+
7
13
  class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
8
14
  def initialize(reflection, associated_class = nil)
9
15
  super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
@@ -153,7 +159,7 @@ module ActiveRecord
153
159
  association = association_instance_get(name)
154
160
 
155
161
  if association.nil?
156
- reflection = self.class.reflect_on_association(name)
162
+ raise AssociationNotFoundError.new(self, name) unless reflection = self.class.reflect_on_association(name)
157
163
  association = reflection.association_class.new(self, reflection)
158
164
  association_instance_set(name, association)
159
165
  end
@@ -22,6 +22,7 @@ module ActiveRecord::Associations::Builder
22
22
  def add_counter_cache_callbacks(reflection)
23
23
  cache_column = reflection.counter_cache_column
24
24
  foreign_key = reflection.foreign_key
25
+ klass = reflection.class_name.safe_constantize
25
26
 
26
27
  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
27
28
  def belongs_to_counter_cache_after_create_for_#{name}
@@ -43,8 +44,8 @@ module ActiveRecord::Associations::Builder
43
44
  def belongs_to_counter_cache_after_update_for_#{name}
44
45
  if (@_after_create_counter_called ||= false)
45
46
  @_after_create_counter_called = false
46
- elsif self.#{foreign_key}_changed? && !new_record? && defined?(#{name.to_s.camelize})
47
- model = #{name.to_s.camelize}
47
+ elsif self.#{foreign_key}_changed? && !new_record? && #{constructable?}
48
+ model = #{klass}
48
49
  foreign_key_was = self.#{foreign_key}_was
49
50
  foreign_key = self.#{foreign_key}
50
51
 
@@ -61,8 +62,6 @@ module ActiveRecord::Associations::Builder
61
62
  model.after_create "belongs_to_counter_cache_after_create_for_#{name}"
62
63
  model.before_destroy "belongs_to_counter_cache_before_destroy_for_#{name}"
63
64
  model.after_update "belongs_to_counter_cache_after_update_for_#{name}"
64
-
65
- klass = reflection.class_name.safe_constantize
66
65
  klass.attr_readonly cache_column if klass && klass.respond_to?(:attr_readonly)
67
66
  end
68
67
 
@@ -118,11 +118,11 @@ module ActiveRecord
118
118
  end
119
119
 
120
120
  def create(attributes = {}, &block)
121
- create_record(attributes, &block)
121
+ _create_record(attributes, &block)
122
122
  end
123
123
 
124
124
  def create!(attributes = {}, &block)
125
- create_record(attributes, true, &block)
125
+ _create_record(attributes, true, &block)
126
126
  end
127
127
 
128
128
  # Add +records+ to this association. Returns +self+ so method calls may
@@ -226,7 +226,7 @@ module ActiveRecord
226
226
  ActiveRecord::Base.logger ? ActiveRecord::Base.logger.warn(message) : $stderr.puts(message)
227
227
  end
228
228
 
229
- if loaded? || dependent == :destroy
229
+ if (loaded? || dependent == :destroy) && dependent != :delete_all
230
230
  delete_or_destroy(load_target, dependent)
231
231
  else
232
232
  delete_records(:all, dependent)
@@ -449,13 +449,13 @@ module ActiveRecord
449
449
  persisted + memory
450
450
  end
451
451
 
452
- def create_record(attributes, raise = false, &block)
452
+ def _create_record(attributes, raise = false, &block)
453
453
  unless owner.persisted?
454
454
  raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
455
455
  end
456
456
 
457
457
  if attributes.is_a?(Array)
458
- attributes.collect { |attr| create_record(attr, raise, &block) }
458
+ attributes.collect { |attr| _create_record(attr, raise, &block) }
459
459
  else
460
460
  transaction do
461
461
  add_to_target(build_record(attributes)) do |record|
@@ -833,6 +833,10 @@ module ActiveRecord
833
833
  !!@association.include?(record)
834
834
  end
835
835
 
836
+ def arel
837
+ scope.arel
838
+ end
839
+
836
840
  def proxy_association
837
841
  @association
838
842
  end
@@ -849,8 +853,6 @@ module ActiveRecord
849
853
  def scope
850
854
  @association.scope
851
855
  end
852
-
853
- # :nodoc:
854
856
  alias spawn scope
855
857
 
856
858
  # Equivalent to <tt>Array#==</tt>. Returns +true+ if the two arrays
@@ -35,7 +35,7 @@ module ActiveRecord
35
35
  private
36
36
 
37
37
  def count_records
38
- load_target.size
38
+ load_target.reject { |r| r.new_record? }.size
39
39
  end
40
40
 
41
41
  def delete_records(records, method)
@@ -73,15 +73,15 @@ module ActiveRecord
73
73
  [association_scope.limit_value, count].compact.min
74
74
  end
75
75
 
76
- def has_cached_counter?(reflection = reflection)
76
+ def has_cached_counter?(reflection = reflection())
77
77
  owner.attribute_present?(cached_counter_attribute_name(reflection))
78
78
  end
79
79
 
80
- def cached_counter_attribute_name(reflection = reflection)
80
+ def cached_counter_attribute_name(reflection = reflection())
81
81
  options[:counter_cache] || "#{reflection.name}_count"
82
82
  end
83
83
 
84
- def update_counter(difference, reflection = reflection)
84
+ def update_counter(difference, reflection = reflection())
85
85
  if has_cached_counter?(reflection)
86
86
  counter = cached_counter_attribute_name(reflection)
87
87
  owner.class.update_counters(owner.id, counter => difference)
@@ -100,7 +100,7 @@ module ActiveRecord
100
100
  # it will be decremented twice.
101
101
  #
102
102
  # Hence this method.
103
- def inverse_updates_counter_cache?(reflection = reflection)
103
+ def inverse_updates_counter_cache?(reflection = reflection())
104
104
  counter_name = cached_counter_attribute_name(reflection)
105
105
  reflection.klass.reflect_on_all_associations(:belongs_to).any? { |inverse_reflection|
106
106
  inverse_reflection.counter_cache_column == counter_name
@@ -84,12 +84,16 @@ module ActiveRecord
84
84
  @through_records[record.object_id] ||= begin
85
85
  ensure_mutable
86
86
 
87
- through_record = through_association.build
87
+ through_record = through_association.build through_scope_attributes
88
88
  through_record.send("#{source_reflection.name}=", record)
89
89
  through_record
90
90
  end
91
91
  end
92
92
 
93
+ def through_scope_attributes
94
+ scope.where_values_hash(through_association.reflection.name.to_s)
95
+ end
96
+
93
97
  def save_through_record(record)
94
98
  build_through_record(record).save!
95
99
  ensure
@@ -106,7 +106,7 @@ module ActiveRecord
106
106
  ]
107
107
  end
108
108
 
109
- scope_chain_items += [reflection.klass.send(:build_default_scope)].compact
109
+ scope_chain_items += [reflection.klass.send(:build_default_scope, ActiveRecord::Relation.new(reflection.klass, table))].compact
110
110
 
111
111
  scope_chain_items.each do |item|
112
112
  unless item.is_a?(Relation)
@@ -132,34 +132,13 @@ module ActiveRecord
132
132
  end
133
133
 
134
134
  def grouped_records(association)
135
- Hash[
136
- records_by_reflection(association).map do |reflection, records|
137
- [reflection, records.group_by { |record| association_klass(reflection, record) }]
138
- end
139
- ]
140
- end
141
-
142
- def records_by_reflection(association)
143
- records.group_by do |record|
144
- record_class = record.class
145
- reflection = record_class.reflections[association]
146
-
147
- unless reflection
148
- raise ActiveRecord::ConfigurationError, "Association named '#{association}' was not found on #{record_class.name}; " \
149
- "perhaps you misspelled it?"
150
- end
151
-
152
- reflection
153
- end
154
- end
155
-
156
- def association_klass(reflection, record)
157
- if reflection.macro == :belongs_to && reflection.options[:polymorphic]
158
- klass = record.send(reflection.foreign_type)
159
- klass && klass.constantize
160
- else
161
- reflection.klass
135
+ h = {}
136
+ records.each do |record|
137
+ assoc = record.association(association)
138
+ klasses = h[assoc.reflection] ||= {}
139
+ (klasses[assoc.klass] ||= []) << record
162
140
  end
141
+ h
163
142
  end
164
143
 
165
144
  def preloader_for(reflection)
@@ -106,7 +106,7 @@ module ActiveRecord
106
106
  scope.where_values = Array(values[:where]) + Array(preload_values[:where])
107
107
  scope.references_values = Array(values[:references]) + Array(preload_values[:references])
108
108
 
109
- scope.select! preload_values[:select] || values[:select] || table[Arel.star]
109
+ scope._select! preload_values[:select] || values[:select] || table[Arel.star]
110
110
  scope.includes! preload_values[:includes] || values[:includes]
111
111
 
112
112
  if options[:as]