/usr/lib/ruby/vendor_ruby/active_record/associations/association_scope.rb is in ruby-activerecord-3.2 3.2.16-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | module ActiveRecord
module Associations
class AssociationScope #:nodoc:
include JoinHelper
attr_reader :association, :alias_tracker
delegate :klass, :owner, :reflection, :interpolate, :to => :association
delegate :chain, :conditions, :options, :source_options, :active_record, :to => :reflection
def initialize(association)
@association = association
@alias_tracker = AliasTracker.new klass.connection
end
def scope
scope = klass.unscoped
scope = scope.extending(*Array.wrap(options[:extend]))
# It's okay to just apply all these like this. The options will only be present if the
# association supports that option; this is enforced by the association builder.
scope = scope.apply_finder_options(options.slice(
:readonly, :include, :order, :limit, :joins, :group, :having, :offset, :select))
if options[:through] && !options[:include]
scope = scope.includes(source_options[:include])
end
scope = scope.uniq if options[:uniq]
add_constraints(scope)
end
private
def add_constraints(scope)
tables = construct_tables
chain.each_with_index do |reflection, i|
table, foreign_table = tables.shift, tables.first
if reflection.source_macro == :has_and_belongs_to_many
join_table = tables.shift
scope = scope.joins(join(
join_table,
table[reflection.association_primary_key].
eq(join_table[reflection.association_foreign_key])
))
table, foreign_table = join_table, tables.first
end
if reflection.source_macro == :belongs_to
if reflection.options[:polymorphic]
key = reflection.association_primary_key(klass)
else
key = reflection.association_primary_key
end
foreign_key = reflection.foreign_key
else
key = reflection.foreign_key
foreign_key = reflection.active_record_primary_key
end
conditions = self.conditions[i]
if reflection == chain.last
scope = scope.where(table[key].eq(owner[foreign_key]))
if reflection.type
scope = scope.where(table[reflection.type].eq(owner.class.base_class.name))
end
conditions.each do |condition|
if options[:through] && condition.is_a?(Hash)
condition = disambiguate_condition(table, condition)
end
scope = scope.where(interpolate(condition))
end
else
constraint = table[key].eq(foreign_table[foreign_key])
if reflection.type
type = chain[i + 1].klass.base_class.name
constraint = constraint.and(table[reflection.type].eq(type))
end
scope = scope.joins(join(foreign_table, constraint))
unless conditions.empty?
scope = scope.where(sanitize(conditions, table))
end
end
end
scope
end
def alias_suffix
reflection.name
end
def table_name_for(reflection)
if reflection == self.reflection
# If this is a polymorphic belongs_to, we want to get the klass from the
# association because it depends on the polymorphic_type attribute of
# the owner
klass.table_name
else
reflection.table_name
end
end
def disambiguate_condition(table, condition)
if condition.is_a?(Hash)
Hash[
condition.map do |k, v|
if v.is_a?(Hash)
[k, v]
else
[table.table_alias || table.name, { k => v }]
end
end
]
else
condition
end
end
end
end
end
|