aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/associations')
-rw-r--r--activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb4
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb8
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb31
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb17
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb15
-rw-r--r--activerecord/lib/active_record/associations/preloader/association.rb1
-rw-r--r--activerecord/lib/active_record/associations/preloader/through_association.rb1
-rw-r--r--activerecord/lib/active_record/associations/singular_association.rb8
8 files changed, 54 insertions, 31 deletions
diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
index 34a555dfd4..357b28ac94 100644
--- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
+++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
@@ -11,7 +11,7 @@ module ActiveRecord::Associations::Builder
end
def join_table
- @join_table ||= [@lhs_class.table_name, klass.table_name].sort.join("\0").gsub(/^(.*[._])(.+)\0\1(.+)/, '\1\2_\3').gsub("\0", "_")
+ @join_table ||= [@lhs_class.table_name, klass.table_name].sort.join("\0").gsub(/^(.*[._])(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
end
private
@@ -98,7 +98,7 @@ module ActiveRecord::Associations::Builder
def middle_options(join_model)
middle_options = {}
- middle_options[:class] = join_model
+ middle_options[:class_name] = "#{lhs_model.name}::#{join_model.name}"
middle_options[:source] = join_model.left_reflection.name
if options.key? :foreign_key
middle_options[:foreign_key] = options[:foreign_key]
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index c5dff7ee1a..93f611dd8d 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -413,7 +413,13 @@ module ActiveRecord
private
def get_records
- return scope.to_a if reflection.scope_chain.any?(&:any?) || scope.eager_loading?
+ if reflection.scope_chain.any?(&:any?) ||
+ scope.eager_loading? ||
+ klass.current_scope ||
+ klass.default_scopes.any?
+
+ return scope.to_a
+ end
conn = klass.connection
sc = reflection.association_scope_cache(conn, owner) do
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 8c7b0b4be9..060b2278d9 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -355,14 +355,15 @@ module ActiveRecord
@association.replace(other_array)
end
- # Deletes all the records from the collection. For +has_many+ associations,
- # the deletion is done according to the strategy specified by the <tt>:dependent</tt>
- # option.
+ # Deletes all the records from the collection according to the strategy
+ # specified by the +:dependent+ option. If no +:dependent+ option is given,
+ # then it will follow the default strategy.
#
- # If no <tt>:dependent</tt> option is given, then it will follow the
- # default strategy. The default strategy is <tt>:nullify</tt>. This
- # sets the foreign keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>,
- # the default strategy is +delete_all+.
+ # For +has_many :through+ associations, the default deletion strategy is
+ # +:delete_all+.
+ #
+ # For +has_many+ associations, the default deletion strategy is +:nullify+.
+ # This sets the foreign keys to +NULL+.
#
# class Person < ActiveRecord::Base
# has_many :pets # dependent: :nullify option by default
@@ -393,9 +394,9 @@ module ActiveRecord
# # #<Pet id: 3, name: "Choo-Choo", person_id: nil>
# # ]
#
- # If it is set to <tt>:destroy</tt> all the objects from the collection
- # are removed by calling their +destroy+ method. See +destroy+ for more
- # information.
+ # Both +has_many+ and +has_many :through+ dependencies default to the
+ # +:delete_all+ strategy if the +:dependent+ option is set to +:destroy+.
+ # Records are not instantiated and callbacks will not be fired.
#
# class Person < ActiveRecord::Base
# has_many :pets, dependent: :destroy
@@ -410,11 +411,6 @@ module ActiveRecord
# # ]
#
# person.pets.delete_all
- # # => [
- # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
- # # #<Pet id: 2, name: "Spook", person_id: 1>,
- # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
- # # ]
#
# Pet.find(1, 2, 3)
# # => ActiveRecord::RecordNotFound
@@ -443,8 +439,9 @@ module ActiveRecord
end
# Deletes the records of the collection directly from the database
- # ignoring the +:dependent+ option. It invokes +before_remove+,
- # +after_remove+ , +before_destroy+ and +after_destroy+ callbacks.
+ # ignoring the +:dependent+ option. Records are instantiated and it
+ # invokes +before_remove+, +after_remove+ , +before_destroy+ and
+ # +after_destroy+ callbacks.
#
# class Person < ActiveRecord::Base
# has_many :pets
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index 455a540bdb..bde23fc116 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/string/filters'
+
module ActiveRecord
# = Active Record Has Many Through Association
module Associations
@@ -63,11 +65,12 @@ module ActiveRecord
save_through_record(record)
if has_cached_counter? && !through_reflection_updates_counter_cache?
- ActiveSupport::Deprecation.warn \
- "Automatic updating of counter caches on through associations has been " \
- "deprecated, and will be removed in Rails 5.0. Instead, please set the " \
- "appropriate counter_cache options on the has_many and belongs_to for " \
- "your associations to #{through_reflection.name}."
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ Automatic updating of counter caches on through associations has been
+ deprecated, and will be removed in Rails 5. Instead, please set the
+ appropriate `counter_cache` options on the `has_many` and `belongs_to`
+ for your associations to #{through_reflection.name}.
+ MSG
update_counter_in_database(1)
end
@@ -158,8 +161,8 @@ module ActiveRecord
if scope.klass.primary_key
count = scope.destroy_all.length
else
- scope.to_a.each do |record|
- record.run_destroy_callbacks
+ scope.each do |record|
+ record._run_destroy_callbacks
end
arel = scope.arel
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index ec5c189cd3..c5c4edd090 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -142,11 +142,20 @@ module ActiveRecord
parents = model_cache[join_root]
column_aliases = aliases.column_aliases join_root
- result_set.each { |row_hash|
- parent = parents[row_hash[primary_key]] ||= join_root.instantiate(row_hash, column_aliases)
- construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
+ message_bus = ActiveSupport::Notifications.instrumenter
+
+ payload = {
+ record_count: result_set.length,
+ class_name: join_root.base_klass.name
}
+ message_bus.instrument('instantiation.active_record', payload) do
+ result_set.each { |row_hash|
+ parent = parents[row_hash[primary_key]] ||= join_root.instantiate(row_hash, column_aliases)
+ construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
+ }
+ end
+
parents.values
end
diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb
index c0639742be..496c426986 100644
--- a/activerecord/lib/active_record/associations/preloader/association.rb
+++ b/activerecord/lib/active_record/associations/preloader/association.rb
@@ -159,6 +159,7 @@ module ActiveRecord
scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
end
+ scope.unscope_values = Array(values[:unscope])
klass.default_scoped.merge(scope)
end
end
diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb
index d57da366bd..12bf3ef138 100644
--- a/activerecord/lib/active_record/associations/preloader/through_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/through_association.rb
@@ -81,6 +81,7 @@ module ActiveRecord
unless reflection_scope.where_values.empty?
scope.includes_values = Array(reflection_scope.values[:includes] || options[:source])
scope.where_values = reflection_scope.values[:where]
+ scope.bind_values = reflection_scope.bind_values
end
scope.references! reflection_scope.values[:references]
diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb
index b9326b9683..c44242a0f0 100644
--- a/activerecord/lib/active_record/associations/singular_association.rb
+++ b/activerecord/lib/active_record/associations/singular_association.rb
@@ -39,7 +39,13 @@ module ActiveRecord
end
def get_records
- return scope.limit(1).to_a if reflection.scope_chain.any?(&:any?) || scope.eager_loading?
+ if reflection.scope_chain.any?(&:any?) ||
+ scope.eager_loading? ||
+ klass.current_scope ||
+ klass.default_scopes.any?
+
+ return scope.limit(1).to_a
+ end
conn = klass.connection
sc = reflection.association_scope_cache(conn, owner) do