aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/reflection.rb
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2014-10-18 14:53:21 -0400
committereileencodes <eileencodes@gmail.com>2015-01-02 17:15:30 -0500
commit08acb4bccba5b64a233eb7c2ea1b0cd09881d2cb (patch)
treeab8916e6923a4ca2c31db8dbbb0ad85f48cd5f5f /activerecord/lib/active_record/reflection.rb
parent9b366b95f9aeb50388af6d247944ed63751b570a (diff)
downloadrails-08acb4bccba5b64a233eb7c2ea1b0cd09881d2cb.tar.gz
rails-08acb4bccba5b64a233eb7c2ea1b0cd09881d2cb.tar.bz2
rails-08acb4bccba5b64a233eb7c2ea1b0cd09881d2cb.zip
Add PolymorphicReflection and constraints method
`#constraints` builds a flattened version of `scope_chain` to allow it to be accessible without requiring an index when iterating over the `scope_chain`
Diffstat (limited to 'activerecord/lib/active_record/reflection.rb')
-rw-r--r--activerecord/lib/active_record/reflection.rb59
1 files changed, 58 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index dd746a4e10..1bc92b1587 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -161,7 +161,12 @@ module ActiveRecord
macro
end
+
+ def constraints
+ scope ? [scope] : []
+ end
end
+
# Base class for AggregateReflection and AssociationReflection. Objects of
# AggregateReflection and AssociationReflection are returned by the Reflection::ClassMethods.
#
@@ -697,13 +702,59 @@ module ActiveRecord
def chain
@chain ||= begin
a = source_reflection.chain
- b = through_reflection.chain
+ b = through_reflection.chain.map(&:dup)
+
+ if options[:source_type]
+ b[0] = PolymorphicReflection.new(b[0], self)
+ end
+
chain = a + b
chain[0] = self # Use self so we don't lose the information from :source_type
chain
end
end
+ class PolymorphicReflection
+ def initialize(reflection, prev_reflection)
+ @reflection = reflection
+ @prev_reflection = prev_reflection
+ end
+
+ def klass
+ @reflection.klass
+ end
+
+ def scope
+ @reflection.scope
+ end
+
+ def table_name
+ @reflection.table_name
+ end
+
+ def plural_name
+ @reflection.plural_name
+ end
+
+ def join_keys(assoc_klass)
+ @reflection.join_keys(assoc_klass)
+ end
+
+ def type
+ @reflection.type
+ end
+
+ def constraints
+ [source_type_info]
+ end
+
+ def source_type_info
+ type = @prev_reflection.foreign_type
+ source_type = @prev_reflection.options[:source_type]
+ lambda { |object| where(type => source_type) }
+ end
+ end
+
# Consider the following example:
#
# class Person
@@ -855,6 +906,12 @@ module ActiveRecord
check_validity_of_inverse!
end
+ def constraints
+ scope_chain = source_reflection.constraints
+ scope_chain << scope if scope
+ scope_chain
+ end
+
protected
def actual_source_reflection # FIXME: this is a horrible name