activerecord 4.2.2 → 4.2.3.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 +4 -4
  2. data/CHANGELOG.md +116 -1
  3. data/lib/active_record.rb +1 -0
  4. data/lib/active_record/association_relation.rb +13 -0
  5. data/lib/active_record/associations.rb +1 -1
  6. data/lib/active_record/associations/belongs_to_association.rb +5 -1
  7. data/lib/active_record/associations/builder/association.rb +1 -1
  8. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -1
  9. data/lib/active_record/associations/collection_proxy.rb +8 -7
  10. data/lib/active_record/associations/has_many_through_association.rb +1 -1
  11. data/lib/active_record/associations/join_dependency.rb +6 -1
  12. data/lib/active_record/associations/through_association.rb +1 -1
  13. data/lib/active_record/attribute_assignment.rb +1 -1
  14. data/lib/active_record/attribute_methods/dirty.rb +6 -1
  15. data/lib/active_record/base.rb +4 -5
  16. data/lib/active_record/callbacks.rb +6 -6
  17. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +6 -2
  18. data/lib/active_record/connection_adapters/abstract/database_statements.rb +4 -0
  19. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +14 -22
  20. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +27 -13
  21. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -5
  22. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +6 -0
  23. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -1
  24. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -1
  25. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +17 -5
  26. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +2 -4
  27. data/lib/active_record/connection_adapters/postgresql_adapter.rb +7 -3
  28. data/lib/active_record/core.rb +17 -12
  29. data/lib/active_record/errors.rb +2 -2
  30. data/lib/active_record/explain_subscriber.rb +1 -1
  31. data/lib/active_record/fixtures.rb +8 -6
  32. data/lib/active_record/gem_version.rb +2 -2
  33. data/lib/active_record/migration.rb +1 -2
  34. data/lib/active_record/persistence.rb +5 -3
  35. data/lib/active_record/railties/databases.rake +1 -1
  36. data/lib/active_record/reflection.rb +2 -2
  37. data/lib/active_record/relation/delegation.rb +1 -1
  38. data/lib/active_record/relation/finder_methods.rb +3 -15
  39. data/lib/active_record/relation/predicate_builder.rb +11 -2
  40. data/lib/active_record/relation/query_methods.rb +13 -16
  41. data/lib/active_record/tasks/database_tasks.rb +1 -1
  42. data/lib/active_record/transactions.rb +14 -6
  43. data/lib/active_record/type/boolean.rb +1 -0
  44. data/lib/active_record/type/hash_lookup_type_map.rb +8 -2
  45. data/lib/active_record/type/serialized.rb +7 -1
  46. data/lib/active_record/validations/uniqueness.rb +9 -5
  47. metadata +8 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c58e37f938f1b191aae7dc072855233d2a16869
4
- data.tar.gz: 3fd75f81060dc6bc6948881f937d6d228979afd6
3
+ metadata.gz: cadb9020dd9e97b773e52e7f2afbc42899929a17
4
+ data.tar.gz: d118851131f2f1a6db81482186a57439e0275ebb
5
5
  SHA512:
6
- metadata.gz: 910b487082d856ff0fd926c1a5f007f2065d08c3025bad011209abd5d7fabc3b54a1388cdf9bca52b7bb53782debd0790a367cae77c7a17aa70b7fdbd07f04df
7
- data.tar.gz: 48c68a32f0eabfe5a4a447c75272398d9f618a199e1ffd6cb95b555ac3d27b14d7327df635e86b71b30b508c5c8aeca9f80012389b9f7e93e642b178c92aa962
6
+ metadata.gz: 0e819d7db757ae3e2e05ee5a21ac25923073cf60e6a106c734572bdab59ac2ed56c85434ea1966d57e6f8bbbf469dc164753b1a703a928c45eff43395024cf85
7
+ data.tar.gz: fdeb6b77c01702951b9897abcf07991e2f56925d9b374eb6c4f66e349142b6a128754939be2ab59e42a82afaec60cafcea88254360d538f2c53e4a24372e6f8f
@@ -1,9 +1,124 @@
1
+ ## Rails 4.2.3 (June 22, 2015) ##
2
+
3
+ * Let `WITH` queries (Common Table Expressions) be explainable.
4
+
5
+ *Vladimir Kochnev*
6
+
7
+ * Fix n+1 query problem when eager loading nil associations (fixes #18312)
8
+
9
+ *Sammy Larbi*
10
+
11
+ * Fixed an error which would occur in dirty checking when calling
12
+ `update_attributes` from a getter.
13
+
14
+ Fixes #20531.
15
+
16
+ *Sean Griffin*
17
+
18
+ * Ensure symbols passed to `ActiveRecord::Relation#select` are always treated
19
+ as columns.
20
+
21
+ Fixes #20360.
22
+
23
+ *Sean Griffin*
24
+
25
+ * Clear query cache when `ActiveRecord::Base#reload` is called.
26
+
27
+ *Shane Hender*
28
+
29
+ * Pass `:extend` option for `has_and_belongs_to_many` associations to the
30
+ underlying `has_many :through`.
31
+
32
+ *Jaehyun Shin*
33
+
34
+ * Make `unscope` aware of "less than" and "greater than" conditions.
35
+
36
+ *TAKAHASHI Kazuaki*
37
+
38
+ * Revert behavior of `db:schema:load` back to loading the full
39
+ environment. This ensures that initializers are run.
40
+
41
+ Fixes #19545.
42
+
43
+ *Yves Senn*
44
+
45
+ * Fix missing index when using `timestamps` with the `index` option.
46
+
47
+ The `index` option used with `timestamps` should be passed to both
48
+ `column` definitions for `created_at` and `updated_at` rather than just
49
+ the first.
50
+
51
+ *Paul Mucur*
52
+
53
+ * Rename `:class` to `:anonymous_class` in association options.
54
+
55
+ Fixes #19659.
56
+
57
+ *Andrew White*
58
+
59
+ * Fixed a bug where uniqueness validations would error on out of range values,
60
+ even if an validation should have prevented it from hitting the database.
61
+
62
+ *Andrey Voronkov*
63
+
64
+ * Foreign key related methods in the migration DSL respect
65
+ `ActiveRecord::Base.pluralize_table_names = false`.
66
+
67
+ Fixes #19643.
68
+
69
+ *Mehmet Emin İNAÇ*
70
+
71
+ * Reduce memory usage from loading types on pg.
72
+
73
+ Fixes #19578.
74
+
75
+ *Sean Griffin*
76
+
77
+ * Fix referencing wrong table aliases while joining tables of has many through
78
+ association (only when calling calculation methods).
79
+
80
+ Fixes #19276.
81
+
82
+ *pinglamb*
83
+
84
+ * Don't attempt to update counter caches, when the column wasn't selected.
85
+
86
+ Fixes #19437.
87
+
88
+ *Sean Griffin*
89
+
90
+ * Correctly persist a serialized attribute that has been returned to
91
+ its default value by an in-place modification.
92
+
93
+ Fixes #19467.
94
+
95
+ *Matthew Draper*
96
+
97
+ * Fix default `format` value in `ActiveRecord::Tasks::DatabaseTasks#schema_file`.
98
+
99
+ *James Cox*
100
+
101
+ * Dont enroll records in the transaction if they dont have commit callbacks.
102
+ That was causing a memory grow problem when creating a lot of records inside a transaction.
103
+
104
+ Fixes #15549.
105
+
106
+ *Will Bryant*, *Aaron Patterson*
107
+
108
+ * Correctly create through records when created on a has many through
109
+ association when using `where`.
110
+
111
+ Fixes #19073.
112
+
113
+ *Sean Griffin*
114
+
115
+
1
116
  ## Rails 4.2.2 (June 16, 2015) ##
2
117
 
3
118
  * No Changes *
4
119
 
5
120
 
6
- ## Rails 4.2.1 (March 19, 2014) ##
121
+ ## Rails 4.2.1 (March 19, 2015) ##
7
122
 
8
123
  * Fixed ActiveRecord::Relation#becomes! and changed_attributes issues for type column
9
124
 
@@ -52,6 +52,7 @@ module ActiveRecord
52
52
  autoload :QueryCache
53
53
  autoload :Querying
54
54
  autoload :ReadonlyAttributes
55
+ autoload :RecordInvalid, 'active_record/validations'
55
56
  autoload :Reflection
56
57
  autoload :RuntimeRegistry
57
58
  autoload :Sanitization
@@ -13,6 +13,19 @@ module ActiveRecord
13
13
  other == to_a
14
14
  end
15
15
 
16
+ def build(*args, &block)
17
+ scoping { @association.build(*args, &block) }
18
+ end
19
+ alias new build
20
+
21
+ def create(*args, &block)
22
+ scoping { @association.create(*args, &block) }
23
+ end
24
+
25
+ def create!(*args, &block)
26
+ scoping { @association.create!(*args, &block) }
27
+ end
28
+
16
29
  private
17
30
 
18
31
  def exec_queries
@@ -1713,7 +1713,7 @@ module ActiveRecord
1713
1713
  hm_options[:through] = middle_reflection.name
1714
1714
  hm_options[:source] = join_model.right_reflection.name
1715
1715
 
1716
- [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name].each do |k|
1716
+ [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k|
1717
1717
  hm_options[k] = options[k] if options.key? k
1718
1718
  end
1719
1719
 
@@ -68,7 +68,7 @@ module ActiveRecord
68
68
  def increment_counter(counter_cache_name)
69
69
  if foreign_key_present?
70
70
  klass.increment_counter(counter_cache_name, target_id)
71
- if target && !stale_target?
71
+ if target && !stale_target? && counter_cache_available_in_memory?(counter_cache_name)
72
72
  target.increment(counter_cache_name)
73
73
  end
74
74
  end
@@ -110,6 +110,10 @@ module ActiveRecord
110
110
  result = owner._read_attribute(reflection.foreign_key)
111
111
  result && result.to_s
112
112
  end
113
+
114
+ def counter_cache_available_in_memory?(counter_cache_name)
115
+ target.respond_to?(counter_cache_name)
116
+ end
113
117
  end
114
118
  end
115
119
  end
@@ -21,7 +21,7 @@ module ActiveRecord::Associations::Builder
21
21
  end
22
22
  self.extensions = []
23
23
 
24
- self.valid_options = [:class_name, :class, :foreign_key, :validate]
24
+ self.valid_options = [:class_name, :anonymous_class, :foreign_key, :validate]
25
25
 
26
26
  attr_reader :name, :scope, :options
27
27
 
@@ -78,7 +78,7 @@ module ActiveRecord::Associations::Builder
78
78
  join_model.table_name_resolver = habtm
79
79
  join_model.class_resolver = lhs_model
80
80
 
81
- join_model.add_left_association :left_side, class: lhs_model
81
+ join_model.add_left_association :left_side, anonymous_class: lhs_model
82
82
  join_model.add_right_association association_name, belongs_to_options(options)
83
83
  join_model
84
84
  end
@@ -470,15 +470,16 @@ module ActiveRecord
470
470
  @association.destroy_all
471
471
  end
472
472
 
473
- # Deletes the +records+ supplied and removes them from the collection. For
474
- # +has_many+ associations, the deletion is done according to the strategy
475
- # specified by the <tt>:dependent</tt> option. Returns an array with the
473
+ # Deletes the +records+ supplied from the collection according to the strategy
474
+ # specified by the +:dependent+ option. If no +:dependent+ option is given,
475
+ # then it will follow the default strategy. Returns an array with the
476
476
  # deleted records.
477
477
  #
478
- # If no <tt>:dependent</tt> option is given, then it will follow the default
479
- # strategy. The default strategy is <tt>:nullify</tt>. This sets the foreign
480
- # keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>, the default
481
- # strategy is +delete_all+.
478
+ # For +has_many :through+ associations, the default deletion strategy is
479
+ # +:delete_all+.
480
+ #
481
+ # For +has_many+ associations, the default deletion strategy is +:nullify+.
482
+ # This sets the foreign keys to +NULL+.
482
483
  #
483
484
  # class Person < ActiveRecord::Base
484
485
  # has_many :pets # dependent: :nullify option by default
@@ -162,7 +162,7 @@ module ActiveRecord
162
162
  count = scope.destroy_all.length
163
163
  else
164
164
  scope.each do |record|
165
- record._run_destroy_callbacks
165
+ record.run_callbacks :destroy
166
166
  end
167
167
 
168
168
  arel = scope.arel
@@ -233,6 +233,7 @@ module ActiveRecord
233
233
  end
234
234
 
235
235
  def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
236
+ return if ar_parent.nil?
236
237
  primary_id = ar_parent.id
237
238
 
238
239
  parent.children.each do |node|
@@ -249,7 +250,11 @@ module ActiveRecord
249
250
 
250
251
  key = aliases.column_alias(node, node.primary_key)
251
252
  id = row[key]
252
- next if id.nil?
253
+ if id.nil?
254
+ nil_association = ar_parent.association(node.reflection.name)
255
+ nil_association.loaded!
256
+ next
257
+ end
253
258
 
254
259
  model = seen[parent.base_klass][primary_id][node.base_klass][id]
255
260
 
@@ -18,7 +18,7 @@ module ActiveRecord
18
18
 
19
19
  reflection_scope = reflection.scope
20
20
  if reflection_scope && reflection_scope.arity.zero?
21
- relation.merge!(reflection_scope)
21
+ relation = relation.merge(reflection_scope)
22
22
  end
23
23
 
24
24
  scope.merge!(
@@ -52,7 +52,7 @@ module ActiveRecord
52
52
 
53
53
  def _assign_attribute(k, v)
54
54
  public_send("#{k}=", v)
55
- rescue NoMethodError
55
+ rescue NoMethodError, NameError
56
56
  if respond_to?("#{k}=")
57
57
  raise
58
58
  else
@@ -108,6 +108,7 @@ module ActiveRecord
108
108
  end
109
109
 
110
110
  def save_changed_attribute(attr, old_value)
111
+ clear_changed_attributes_cache
111
112
  if attribute_changed_by_setter?(attr)
112
113
  clear_attribute_changes(attr) unless _field_changed?(attr, old_value)
113
114
  else
@@ -178,7 +179,11 @@ module ActiveRecord
178
179
  @cached_changed_attributes = changed_attributes
179
180
  yield
180
181
  ensure
181
- remove_instance_variable(:@cached_changed_attributes)
182
+ clear_changed_attributes_cache
183
+ end
184
+
185
+ def clear_changed_attributes_cache
186
+ remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes)
182
187
  end
183
188
  end
184
189
  end
@@ -119,23 +119,22 @@ module ActiveRecord #:nodoc:
119
119
  # All column values are automatically available through basic accessors on the Active Record
120
120
  # object, but sometimes you want to specialize this behavior. This can be done by overwriting
121
121
  # the default accessors (using the same name as the attribute) and calling
122
- # <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually
123
- # change things.
122
+ # +super+ to actually change things.
124
123
  #
125
124
  # class Song < ActiveRecord::Base
126
125
  # # Uses an integer of seconds to hold the length of the song
127
126
  #
128
127
  # def length=(minutes)
129
- # write_attribute(:length, minutes.to_i * 60)
128
+ # super(minutes.to_i * 60)
130
129
  # end
131
130
  #
132
131
  # def length
133
- # read_attribute(:length) / 60
132
+ # super / 60
134
133
  # end
135
134
  # end
136
135
  #
137
136
  # You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt>
138
- # instead of <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>.
137
+ # or <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>.
139
138
  #
140
139
  # == Attribute query methods
141
140
  #
@@ -199,7 +199,7 @@ module ActiveRecord
199
199
  # == Canceling callbacks
200
200
  #
201
201
  # If a <tt>before_*</tt> callback returns +false+, all the later callbacks and the associated action are
202
- # cancelled. If an <tt>after_*</tt> callback returns +false+, all the later callbacks are cancelled.
202
+ # cancelled.
203
203
  # Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
204
204
  # methods on the model, which are called last.
205
205
  #
@@ -289,25 +289,25 @@ module ActiveRecord
289
289
  end
290
290
 
291
291
  def destroy #:nodoc:
292
- _run_destroy_callbacks { super }
292
+ run_callbacks(:destroy) { super }
293
293
  end
294
294
 
295
295
  def touch(*) #:nodoc:
296
- _run_touch_callbacks { super }
296
+ run_callbacks(:touch) { super }
297
297
  end
298
298
 
299
299
  private
300
300
 
301
301
  def create_or_update #:nodoc:
302
- _run_save_callbacks { super }
302
+ run_callbacks(:save) { super }
303
303
  end
304
304
 
305
305
  def _create_record #:nodoc:
306
- _run_create_callbacks { super }
306
+ run_callbacks(:create) { super }
307
307
  end
308
308
 
309
309
  def _update_record(*) #:nodoc:
310
- _run_update_callbacks { super }
310
+ run_callbacks(:update) { super }
311
311
  end
312
312
  end
313
313
  end
@@ -361,7 +361,7 @@ module ActiveRecord
361
361
  synchronize do
362
362
  owner = conn.owner
363
363
 
364
- conn._run_checkin_callbacks do
364
+ conn.run_callbacks :checkin do
365
365
  conn.expire
366
366
  end
367
367
 
@@ -452,10 +452,14 @@ module ActiveRecord
452
452
  end
453
453
 
454
454
  def checkout_and_verify(c)
455
- c._run_checkout_callbacks do
455
+ c.run_callbacks :checkout do
456
456
  c.verify!
457
457
  end
458
458
  c
459
+ rescue
460
+ remove c
461
+ c.disconnect!
462
+ raise
459
463
  end
460
464
  end
461
465
 
@@ -234,6 +234,10 @@ module ActiveRecord
234
234
  current_transaction.add_record(record)
235
235
  end
236
236
 
237
+ def transaction_state
238
+ current_transaction.state
239
+ end
240
+
237
241
  # Begins the transaction (and turns off auto-committing).
238
242
  def begin_db_transaction() end
239
243
 
@@ -57,11 +57,11 @@ module ActiveRecord
57
57
  end
58
58
 
59
59
  module TimestampDefaultDeprecation # :nodoc:
60
- def emit_warning_if_null_unspecified(options)
60
+ def emit_warning_if_null_unspecified(sym, options)
61
61
  return if options.key?(:null)
62
62
 
63
63
  ActiveSupport::Deprecation.warn(<<-MSG.squish)
64
- `#timestamp` was called without specifying an option for `null`. In Rails 5,
64
+ `##{sym}` was called without specifying an option for `null`. In Rails 5,
65
65
  this behavior will change to `null: false`. You should manually specify
66
66
  `null: true` to prevent the behavior of your existing migrations from changing.
67
67
  MSG
@@ -256,6 +256,7 @@ module ActiveRecord
256
256
  def column(name, type, options = {})
257
257
  name = name.to_s
258
258
  type = type.to_sym
259
+ options = options.dup
259
260
 
260
261
  if @columns_hash[name] && @columns_hash[name].primary_key?
261
262
  raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
@@ -297,23 +298,17 @@ module ActiveRecord
297
298
  # t.timestamps null: false
298
299
  def timestamps(*args)
299
300
  options = args.extract_options!
300
- emit_warning_if_null_unspecified(options)
301
+ emit_warning_if_null_unspecified(:timestamps, options)
301
302
  column(:created_at, :datetime, options)
302
303
  column(:updated_at, :datetime, options)
303
304
  end
304
305
 
305
- # Adds a reference. Optionally adds a +type+ column, if
306
- # <tt>:polymorphic</tt> option is provided. <tt>references</tt> and
307
- # <tt>belongs_to</tt> are acceptable. The reference column will be an
308
- # +integer+ by default, the <tt>:type</tt> option can be used to specify
309
- # a different type. A foreign key will be created if a +foreign_key+
310
- # option is passed.
306
+ # Adds a reference.
311
307
  #
312
308
  # t.references(:user)
313
- # t.references(:user, type: "string")
314
- # t.belongs_to(:supplier, polymorphic: true)
309
+ # t.belongs_to(:supplier, foreign_key: true)
315
310
  #
316
- # See SchemaStatements#add_reference
311
+ # See SchemaStatements#add_reference for details of the options you can use.
317
312
  def references(*args)
318
313
  options = args.extract_options!
319
314
  polymorphic = options.delete(:polymorphic)
@@ -329,7 +324,10 @@ module ActiveRecord
329
324
  column("#{col}_id", type, options)
330
325
  column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
331
326
  index(polymorphic ? %w(type id).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
332
- foreign_key(col.to_s.pluralize, foreign_key_options.is_a?(Hash) ? foreign_key_options : {}) if foreign_key_options
327
+ if foreign_key_options
328
+ to_table = Base.pluralize_table_names ? col.to_s.pluralize : col.to_s
329
+ foreign_key(to_table, foreign_key_options.is_a?(Hash) ? foreign_key_options : {})
330
+ end
333
331
  end
334
332
  end
335
333
  alias :belongs_to :references
@@ -535,18 +533,12 @@ module ActiveRecord
535
533
  @base.rename_column(name, column_name, new_column_name)
536
534
  end
537
535
 
538
- # Adds a reference. Optionally adds a +type+ column, if
539
- # <tt>:polymorphic</tt> option is provided. <tt>references</tt> and
540
- # <tt>belongs_to</tt> are acceptable. The reference column will be an
541
- # +integer+ by default, the <tt>:type</tt> option can be used to specify
542
- # a different type. A foreign key will be created if a +foreign_key+
543
- # option is passed.
536
+ # Adds a reference.
544
537
  #
545
538
  # t.references(:user)
546
- # t.references(:user, type: "string")
547
- # t.belongs_to(:supplier, polymorphic: true)
539
+ # t.belongs_to(:supplier, foreign_key: true)
548
540
  #
549
- # See SchemaStatements#add_reference
541
+ # See SchemaStatements#add_reference for details of the options you can use.
550
542
  def references(*args)
551
543
  options = args.extract_options!
552
544
  args.each do |ref_name|