]> git.openstreetmap.org Git - rails.git/blob - config/initializers/composite_primary_keys.rb
Monkey patch CPK to fix problems with polymorphic has_many
[rails.git] / config / initializers / composite_primary_keys.rb
1 module ActiveRecord
2   module Associations
3     class AssociationScope
4       def add_constraints(scope)
5         tables = construct_tables
6
7         chain.each_with_index do |reflection, i|
8           table, foreign_table = tables.shift, tables.first
9
10           if reflection.source_macro == :has_and_belongs_to_many
11             join_table = tables.shift
12
13             # CPK
14             # scope = scope.joins(join(
15             #  join_table,
16             #  table[reflection.active_record_primary_key].
17             #    eq(join_table[reflection.association_foreign_key])
18             #))
19             predicate = cpk_join_predicate(table, reflection.association_primary_key,
20                                            join_table, reflection.association_foreign_key)
21             scope = scope.joins(join(join_table, predicate))
22
23             table, foreign_table = join_table, tables.first
24           end
25
26           if reflection.source_macro == :belongs_to
27             if reflection.options[:polymorphic]
28               key = reflection.association_primary_key(klass)
29             else
30               key = reflection.association_primary_key
31             end
32
33             foreign_key = reflection.foreign_key
34           else
35             key         = reflection.foreign_key
36             foreign_key = reflection.active_record_primary_key
37           end
38
39           conditions = self.conditions[i]
40
41           if reflection == chain.last
42             # CPK
43             # scope = scope.where(table[key].eq(owner[foreign_key]))
44             predicate = cpk_join_predicate(table, key, owner, foreign_key)
45             scope = scope.where(predicate)
46
47             if reflection.type
48               scope = scope.where(table[reflection.type].eq(owner.class.base_class.name))
49             end
50
51             conditions.each do |condition|
52               if options[:through] && condition.is_a?(Hash)
53                 condition = { table.name => condition }
54               end
55
56               scope = scope.where(interpolate(condition))
57             end
58           else
59             # CPK
60             # constraint = table[key].eq(foreign_table[foreign_key])
61             constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
62
63             if reflection.type
64               type = chain[i + 1].klass.base_class.name
65               constraint = constraint.and(table[reflection.type].eq(type))
66             end
67
68             scope = scope.joins(join(foreign_table, constraint))
69
70             unless conditions.empty?
71               scope = scope.where(sanitize(conditions, table))
72             end
73           end
74         end
75
76         scope
77       end
78     end
79   end
80 end