Class: ActiveRecord::Associations::AssociationScope
Do not use. This class is for internal use only.
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
|
|
Inherits: | Object |
Defined in: | activerecord/lib/active_record/associations/association_scope.rb |
Constant Summary
Class Method Summary
Instance Attribute Summary
- #value_transformation readonly private
Instance Method Summary
- #add_constraints(scope, owner, chain)
- #apply_scope(scope, table, key, value)
- #eval_scope(reflection, scope, owner)
- #get_chain(reflection, association, tracker)
- #scope(association)
- #join(table, constraint) private
- #last_chain_scope(scope, reflection, owner) private
- #next_chain_scope(scope, reflection, next_reflection) private
- #transform_value(value) private
Constructor Details
.new(value_transformation) ⇒ AssociationScope
# File 'activerecord/lib/active_record/associations/association_scope.rb', line 15
def initialize(value_transformation) @value_transformation = value_transformation end
Class Method Details
.create(&block)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 10
def self.create(&block) block ||= lambda { |val| val } new(block) end
.get_bind_values(owner, chain)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 34
def self.get_bind_values(owner, chain) binds = [] last_reflection = chain.last binds.push(*last_reflection.join_id_for(owner)) if last_reflection.type binds << owner.class.polymorphic_name end chain.each_cons(2).each do |reflection, next_reflection| if reflection.type binds << next_reflection.klass.polymorphic_name end end binds end
.scope(association)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 6
def self.scope(association) INSTANCE.scope(association) end
Instance Attribute Details
#value_transformation (readonly, private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 52
attr_reader :value_transformation
Instance Method Details
#add_constraints(scope, owner, chain)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 124
def add_constraints(scope, owner, chain) scope = last_chain_scope(scope, chain.last, owner) chain.each_cons(2) do |reflection, next_reflection| scope = next_chain_scope(scope, reflection, next_reflection) end chain_head = chain.first chain.reverse_each do |reflection| reflection.constraints.each do |scope_chain_item| item = eval_scope(reflection, scope_chain_item, owner) if scope_chain_item == chain_head.scope scope.merge! item.except(:where, :includes, :unscope, :order) elsif !item.references_values.empty? scope.merge! item.only(:joins, :left_outer_joins) associations = item.eager_load_values | item.includes_values unless associations.empty? scope.joins! item.construct_join_dependency(associations, Arel::Nodes::OuterJoin) end end reflection.all_includes do scope.includes_values |= item.includes_values end scope.unscope!(*item.unscope_values) scope.where_clause += item.where_clause scope.order_values = item.order_values | scope.order_values end end scope end
#apply_scope(scope, table, key, value)
[ GitHub ]#eval_scope(reflection, scope, owner)
[ GitHub ]#get_chain(reflection, association, tracker)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 112
def get_chain(reflection, association, tracker) name = reflection.name chain = [Reflection::RuntimeReflection.new(reflection, association)] reflection.chain.drop(1).each do |refl| aliased_table = tracker.aliased_table_for(refl.klass.arel_table) do refl.alias_candidate(name) end chain << ReflectionProxy.new(refl, aliased_table) end chain end
#join(table, constraint) (private)
[ GitHub ]#last_chain_scope(scope, reflection, owner) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 58
def last_chain_scope(scope, reflection, owner) primary_key = Array(reflection.join_primary_key) foreign_key = Array(reflection.join_foreign_key) table = reflection.aliased_table primary_key_foreign_key_pairs = primary_key.zip(foreign_key) primary_key_foreign_key_pairs.each do |join_key, foreign_key| value = transform_value(owner._read_attribute(foreign_key)) scope = apply_scope(scope, table, join_key, value) end if reflection.type polymorphic_type = transform_value(owner.class.polymorphic_name) scope = apply_scope(scope, table, reflection.type, polymorphic_type) end scope end
#next_chain_scope(scope, reflection, next_reflection) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 81
def next_chain_scope(scope, reflection, next_reflection) primary_key = Array(reflection.join_primary_key) foreign_key = Array(reflection.join_foreign_key) table = reflection.aliased_table foreign_table = next_reflection.aliased_table primary_key_foreign_key_pairs = primary_key.zip(foreign_key) constraints = primary_key_foreign_key_pairs.map do |join_primary_key, foreign_key| table[join_primary_key].eq(foreign_table[foreign_key]) end.inject(&:and) if reflection.type value = transform_value(next_reflection.klass.polymorphic_name) scope = apply_scope(scope, table, reflection.type, value) end scope.joins!(join(foreign_table, constraints)) end
#scope(association)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 21
def scope(association) klass = association.klass reflection = association.reflection scope = klass.unscoped owner = association.owner chain = get_chain(reflection, association, scope.alias_tracker) scope.extending! reflection.extensions scope = add_constraints(scope, owner, chain) scope.limit!(1) unless reflection.collection? scope end
#transform_value(value) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/association_scope.rb', line 77
def transform_value(value) value_transformation.call(value) end