activerecord 5.0.5 → 5.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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ed855b32576503d9b5b55e601f1504ec5af4298c
4
- data.tar.gz: f2b29832dcca353efbcdd3771a03f2a464bc0df6
3
+ metadata.gz: ef1a22534c4086164c0e30f550fef12e900cf9a6
4
+ data.tar.gz: e237245c3105be1f05652407b6dcdef6f7d85938
5
5
  SHA512:
6
- metadata.gz: 73225e612d84e880d1ad325bc53268e6bd67b02147190f3ea5b6d0c79fbb3a84d69cd66d32c0a4b6d566352f0d8dcc031e3e22df5216f03651f7b40d0b68fa71
7
- data.tar.gz: 03f83e492e88da43185e272dcd2cca677f375c17be16c3e5488fedcd6345fdf5306aa691b8eb393f9f680efb292a5c7b4a27189c8e3d6f179b55992472904a6b
6
+ metadata.gz: 260360a40ec15318044dd83043059ee0bb8be0e928f3844eb3f940eff9c1a5128706553ce11640374166a4518df342d9e0d7ec4b4440859b73a5cb968b832df6
7
+ data.tar.gz: e8f0b708bff9d283de1e39454033643d4d7810288c2a15c91ca02c4e0f78ccf88ee01ce3b0aabf9cfff37a35b3b55ec95d7f715d746c2bcb560b12e59fe2c72a
@@ -1,3 +1,12 @@
1
+ ## Rails 5.0.6.rc1 (August 24, 2017) ##
2
+
3
+ * Ensure `sum` honors `distinct` on `has_many :through` associations
4
+
5
+ Fixes #16791
6
+
7
+ *Aaron Wortham
8
+
9
+
1
10
  ## Rails 5.0.5 (July 31, 2017) ##
2
11
 
3
12
  * No changes.
@@ -317,17 +317,18 @@ module ActiveRecord
317
317
  # | | belongs_to |
318
318
  # generated methods | belongs_to | :polymorphic | has_one
319
319
  # ----------------------------------+------------+--------------+---------
320
- # other(force_reload=false) | X | X | X
320
+ # other | X | X | X
321
321
  # other=(other) | X | X | X
322
322
  # build_other(attributes={}) | X | | X
323
323
  # create_other(attributes={}) | X | | X
324
324
  # create_other!(attributes={}) | X | | X
325
+ # reload_other | X | X | X
325
326
  #
326
327
  # === Collection associations (one-to-many / many-to-many)
327
328
  # | | | has_many
328
329
  # generated methods | habtm | has_many | :through
329
330
  # ----------------------------------+-------+----------+----------
330
- # others(force_reload=false) | X | X | X
331
+ # others | X | X | X
331
332
  # others=(other,other,...) | X | X | X
332
333
  # other_ids | X | X | X
333
334
  # other_ids=(id,id,...) | X | X | X
@@ -351,6 +352,7 @@ module ActiveRecord
351
352
  # others.exists? | X | X | X
352
353
  # others.distinct | X | X | X
353
354
  # others.reset | X | X | X
355
+ # others.reload | X | X | X
354
356
  #
355
357
  # === Overriding generated methods
356
358
  #
@@ -1162,9 +1164,9 @@ module ActiveRecord
1162
1164
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1163
1165
  # <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
1164
1166
  #
1165
- # [collection(force_reload = false)]
1166
- # Returns an array of all the associated objects.
1167
- # An empty array is returned if none are found.
1167
+ # [collection]
1168
+ # Returns a Relation of all the associated objects.
1169
+ # An empty Relation is returned if none are found.
1168
1170
  # [collection<<(object, ...)]
1169
1171
  # Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
1170
1172
  # Note that this operation instantly fires update SQL without waiting for the save or update call on the
@@ -1221,6 +1223,9 @@ module ActiveRecord
1221
1223
  # [collection.create!(attributes = {})]
1222
1224
  # Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
1223
1225
  # if the record is invalid.
1226
+ # [collection.reload]
1227
+ # Returns a Relation of all of the associated objects, forcing a database read.
1228
+ # An empty Relation is returned if none are found.
1224
1229
  #
1225
1230
  # === Example
1226
1231
  #
@@ -1240,6 +1245,7 @@ module ActiveRecord
1240
1245
  # * <tt>Firm#clients.build</tt> (similar to <tt>Client.new("firm_id" => id)</tt>)
1241
1246
  # * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save; c</tt>)
1242
1247
  # * <tt>Firm#clients.create!</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save!</tt>)
1248
+ # * <tt>Firm#clients.reload</tt>
1243
1249
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1244
1250
  #
1245
1251
  # === Scopes
@@ -1376,7 +1382,7 @@ module ActiveRecord
1376
1382
  # +association+ is a placeholder for the symbol passed as the +name+ argument, so
1377
1383
  # <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
1378
1384
  #
1379
- # [association(force_reload = false)]
1385
+ # [association]
1380
1386
  # Returns the associated object. +nil+ is returned if none is found.
1381
1387
  # [association=(associate)]
1382
1388
  # Assigns the associate object, extracts the primary key, sets it as the foreign key,
@@ -1393,6 +1399,8 @@ module ActiveRecord
1393
1399
  # [create_association!(attributes = {})]
1394
1400
  # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1395
1401
  # if the record is invalid.
1402
+ # [reload_association]
1403
+ # Returns the associated object, forcing a database read.
1396
1404
  #
1397
1405
  # === Example
1398
1406
  #
@@ -1402,6 +1410,7 @@ module ActiveRecord
1402
1410
  # * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new("account_id" => id)</tt>)
1403
1411
  # * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save; b</tt>)
1404
1412
  # * <tt>Account#create_beneficiary!</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save!; b</tt>)
1413
+ # * <tt>Account#reload_beneficiary</tt>
1405
1414
  #
1406
1415
  # === Scopes
1407
1416
  #
@@ -1508,7 +1517,7 @@ module ActiveRecord
1508
1517
  # +association+ is a placeholder for the symbol passed as the +name+ argument, so
1509
1518
  # <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
1510
1519
  #
1511
- # [association(force_reload = false)]
1520
+ # [association]
1512
1521
  # Returns the associated object. +nil+ is returned if none is found.
1513
1522
  # [association=(associate)]
1514
1523
  # Assigns the associate object, extracts the primary key, and sets it as the foreign key.
@@ -1522,6 +1531,8 @@ module ActiveRecord
1522
1531
  # [create_association!(attributes = {})]
1523
1532
  # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1524
1533
  # if the record is invalid.
1534
+ # [reload_association]
1535
+ # Returns the associated object, forcing a database read.
1525
1536
  #
1526
1537
  # === Example
1527
1538
  #
@@ -1531,6 +1542,7 @@ module ActiveRecord
1531
1542
  # * <tt>Post#build_author</tt> (similar to <tt>post.author = Author.new</tt>)
1532
1543
  # * <tt>Post#create_author</tt> (similar to <tt>post.author = Author.new; post.author.save; post.author</tt>)
1533
1544
  # * <tt>Post#create_author!</tt> (similar to <tt>post.author = Author.new; post.author.save!; post.author</tt>)
1545
+ # * <tt>Post#reload_author</tt>
1534
1546
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1535
1547
  #
1536
1548
  # === Scopes
@@ -1666,9 +1678,9 @@ module ActiveRecord
1666
1678
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1667
1679
  # <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
1668
1680
  #
1669
- # [collection(force_reload = false)]
1670
- # Returns an array of all the associated objects.
1671
- # An empty array is returned if none are found.
1681
+ # [collection]
1682
+ # Returns a Relation of all the associated objects.
1683
+ # An empty Relation is returned if none are found.
1672
1684
  # [collection<<(object, ...)]
1673
1685
  # Adds one or more objects to the collection by creating associations in the join table
1674
1686
  # (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
@@ -1706,6 +1718,9 @@ module ActiveRecord
1706
1718
  # Returns a new object of the collection type that has been instantiated
1707
1719
  # with +attributes+, linked to this object through the join table, and that has already been
1708
1720
  # saved (if it passed the validation).
1721
+ # [collection.reload]
1722
+ # Returns a Relation of all of the associated objects, forcing a database read.
1723
+ # An empty Relation is returned if none are found.
1709
1724
  #
1710
1725
  # === Example
1711
1726
  #
@@ -1724,6 +1739,7 @@ module ActiveRecord
1724
1739
  # * <tt>Developer#projects.exists?(...)</tt>
1725
1740
  # * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("developer_id" => id)</tt>)
1726
1741
  # * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("developer_id" => id); c.save; c</tt>)
1742
+ # * <tt>Developer#projects.reload</tt>
1727
1743
  # The declaration may include an +options+ hash to specialize the behavior of the association.
1728
1744
  #
1729
1745
  # === Scopes
@@ -67,11 +67,14 @@ module ActiveRecord
67
67
  pk_type = reflection.association_primary_key_type
68
68
  ids = Array(ids).reject(&:blank?)
69
69
  ids.map! { |i| pk_type.cast(i) }
70
- records = klass.where(reflection.association_primary_key => ids).index_by do |r|
71
- r.send(reflection.association_primary_key)
70
+
71
+ primary_key = reflection.association_primary_key
72
+ records = klass.where(primary_key => ids).index_by do |r|
73
+ r.public_send(primary_key)
72
74
  end.values_at(*ids).compact
75
+
73
76
  if records.size != ids.size
74
- klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, reflection.association_primary_key)
77
+ klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key)
75
78
  else
76
79
  replace(records)
77
80
  end
@@ -54,15 +54,13 @@ module ActiveRecord
54
54
  end
55
55
  scope_chain_index += 1
56
56
 
57
+ relation = ActiveRecord::Relation.create(klass, table, predicate_builder)
58
+ current_scope = klass.current_scope
59
+
57
60
  klass_scope =
58
- if klass.current_scope && klass.current_scope.values.empty?
59
- klass.unscoped
61
+ if current_scope && current_scope.empty_scope?
62
+ relation
60
63
  else
61
- relation = ActiveRecord::Relation.create(
62
- klass,
63
- table,
64
- predicate_builder,
65
- )
66
64
  klass.send(:build_default_scope, relation)
67
65
  end
68
66
  scope_chain_items.concat [klass_scope].compact
@@ -166,7 +166,7 @@ module ActiveRecord
166
166
  end
167
167
 
168
168
  scope.unscope_values = Array(values[:unscope]) + Array(preload_values[:unscope])
169
- klass.default_scoped.merge(scope)
169
+ klass.scope_for_association.merge(scope)
170
170
  end
171
171
  end
172
172
  end
@@ -14,7 +14,7 @@ module ActiveRecord
14
14
  def target_scope
15
15
  scope = super
16
16
  reflection.chain.drop(1).each do |reflection|
17
- relation = reflection.klass.all
17
+ relation = reflection.klass.scope_for_association
18
18
  scope.merge!(
19
19
  relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load)
20
20
  )
@@ -7,8 +7,8 @@ module ActiveRecord
7
7
  module VERSION
8
8
  MAJOR = 5
9
9
  MINOR = 0
10
- TINY = 5
11
- PRE = nil
10
+ TINY = 6
11
+ PRE = "rc1"
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
14
  end
@@ -644,6 +644,10 @@ module ActiveRecord
644
644
  Associations::HasManyAssociation
645
645
  end
646
646
  end
647
+
648
+ def association_primary_key(klass = nil)
649
+ primary_key(klass || self.klass)
650
+ end
647
651
  end
648
652
 
649
653
  class HasOneReflection < AssociationReflection # :nodoc:
@@ -347,7 +347,7 @@ module ActiveRecord
347
347
  # Please check unscoped if you want to remove all previous scopes (including
348
348
  # the default_scope) during the execution of a block.
349
349
  def scoping
350
- previous, klass.current_scope = klass.current_scope, self
350
+ previous, klass.current_scope = klass.current_scope(true), self
351
351
  yield
352
352
  ensure
353
353
  klass.current_scope = previous
@@ -689,6 +689,10 @@ module ActiveRecord
689
689
  "#<#{self.class.name} [#{entries.join(', ')}]>"
690
690
  end
691
691
 
692
+ def empty_scope? # :nodoc:
693
+ @values == klass.unscoped.values
694
+ end
695
+
692
696
  protected
693
697
 
694
698
  def load_records(records)
@@ -238,6 +238,10 @@ module ActiveRecord
238
238
 
239
239
  select_value = operation_over_aggregate_column(column, operation, distinct)
240
240
 
241
+ if operation == "sum" && distinct
242
+ select_value.distinct = true
243
+ end
244
+
241
245
  column_alias = select_value.alias
242
246
  column_alias ||= @klass.connection.column_name_for_operation(operation, select_value)
243
247
  relation.select_values = [select_value]
@@ -10,8 +10,8 @@ module ActiveRecord
10
10
  end
11
11
 
12
12
  module ClassMethods
13
- def current_scope #:nodoc:
14
- ScopeRegistry.value_for(:current_scope, self)
13
+ def current_scope(skip_inherited_scope = false) # :nodoc:
14
+ ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
15
15
  end
16
16
 
17
17
  def current_scope=(scope) #:nodoc:
@@ -75,8 +75,9 @@ module ActiveRecord
75
75
  end
76
76
 
77
77
  # Obtains the value for a given +scope_type+ and +model+.
78
- def value_for(scope_type, model)
78
+ def value_for(scope_type, model, skip_inherited_scope = false)
79
79
  raise_invalid_scope_type!(scope_type)
80
+ return @registry[scope_type][model.name] if skip_inherited_scope
80
81
  klass = model
81
82
  base = model.base_class
82
83
  while klass <= base
@@ -29,8 +29,17 @@ module ActiveRecord
29
29
  end
30
30
  end
31
31
 
32
- def default_scoped # :nodoc:
33
- scope = relation
32
+ def scope_for_association(scope = relation) # :nodoc:
33
+ current_scope = self.current_scope
34
+
35
+ if current_scope && current_scope.empty_scope?
36
+ scope
37
+ else
38
+ default_scoped(scope)
39
+ end
40
+ end
41
+
42
+ def default_scoped(scope = relation) # :nodoc:
34
43
  build_default_scope(scope) || scope
35
44
  end
36
45
 
@@ -16,7 +16,7 @@ module ActiveRecord
16
16
  configuration.merge('encoding' => encoding)
17
17
  establish_connection configuration
18
18
  rescue ActiveRecord::StatementInvalid => error
19
- if /database .* already exists/ === error.message
19
+ if error.cause.is_a?(PG::DuplicateDatabase)
20
20
  raise DatabaseAlreadyExists
21
21
  else
22
22
  raise
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.5
4
+ version: 5.0.6.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-31 00:00:00.000000000 Z
11
+ date: 2017-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 5.0.5
19
+ version: 5.0.6.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 5.0.5
26
+ version: 5.0.6.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 5.0.5
33
+ version: 5.0.6.rc1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 5.0.5
40
+ version: 5.0.6.rc1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: arel
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -323,9 +323,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
323
323
  version: 2.2.2
324
324
  required_rubygems_version: !ruby/object:Gem::Requirement
325
325
  requirements:
326
- - - ">="
326
+ - - ">"
327
327
  - !ruby/object:Gem::Version
328
- version: '0'
328
+ version: 1.3.1
329
329
  requirements: []
330
330
  rubyforge_project:
331
331
  rubygems_version: 2.6.12