aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorSean Griffin <sean@seantheprogrammer.com>2015-11-23 13:47:42 -0700
committerSean Griffin <sean@seantheprogrammer.com>2015-11-23 13:47:42 -0700
commit9d79334a1dee67e31222c790e231772deafcaeb8 (patch)
tree5e3d1c7fa0f194460fabd80089d922df59cee9fe /activerecord
parent762982f2325ce04a50f2f56b698b9fb7e606a518 (diff)
downloadrails-9d79334a1dee67e31222c790e231772deafcaeb8.tar.gz
rails-9d79334a1dee67e31222c790e231772deafcaeb8.tar.bz2
rails-9d79334a1dee67e31222c790e231772deafcaeb8.zip
Remove blanket array delegation from `Relation`
As was pointed out by #17128, our blacklist of mutation methods was non-exhaustive (and would need to be kept up to date with each new version of Ruby). Now that `Relation` includes `Enumerable`, the number of methods that we actually need to delegate are pretty small. As such, we can change to explicitly delegating the few non-mutation related methods that `Array` has which aren't on `Enumerable`
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/relation/delegation.rb16
-rw-r--r--activerecord/test/cases/relation/delegation_test.rb6
2 files changed, 2 insertions, 20 deletions
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index 27de313d05..b1333f110c 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -36,13 +36,8 @@ module ActiveRecord
# may vary depending on the klass of a relation, so we create a subclass of Relation
# for each different klass, and the delegations are compiled into that subclass only.
- BLACKLISTED_ARRAY_METHODS = [
- :compact!, :flatten!, :reject!, :reverse!, :rotate!, :map!,
- :shuffle!, :slice!, :sort!, :sort_by!, :delete_if,
- :keep_if, :pop, :shift, :delete_at, :select!
- ].to_set # :nodoc:
-
- delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join, to: :to_a
+ delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join,
+ :[], :&, :|, :+, :-, :sample, :reverse, :compact, to: :to_a
delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
:connection, :columns_hash, :to => :klass
@@ -114,21 +109,14 @@ module ActiveRecord
def respond_to?(method, include_private = false)
super || @klass.respond_to?(method, include_private) ||
- array_delegable?(method) ||
arel.respond_to?(method, include_private)
end
protected
- def array_delegable?(method)
- Array.method_defined?(method) && BLACKLISTED_ARRAY_METHODS.exclude?(method)
- end
-
def method_missing(method, *args, &block)
if @klass.respond_to?(method)
scoping { @klass.public_send(method, *args, &block) }
- elsif array_delegable?(method)
- to_a.public_send(method, *args, &block)
elsif arel.respond_to?(method)
arel.public_send(method, *args, &block)
else
diff --git a/activerecord/test/cases/relation/delegation_test.rb b/activerecord/test/cases/relation/delegation_test.rb
index 989f4e1e5d..b4269bd56d 100644
--- a/activerecord/test/cases/relation/delegation_test.rb
+++ b/activerecord/test/cases/relation/delegation_test.rb
@@ -40,12 +40,6 @@ module ActiveRecord
assert_respond_to target, method
end
end
-
- ActiveRecord::Delegation::BLACKLISTED_ARRAY_METHODS.each do |method|
- define_method "test_#{method}_is_not_delegated_to_Array" do
- assert_raises(NoMethodError) { call_method(target, method) }
- end
- end
end
class DelegationAssociationTest < DelegationTest