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
|
# File 'lib/polymorphic_join.rb', line 13
def query_ref_polymorphic(type, refs)
polymorphic = if refs.nil?
{
refs: retrieve_all_polymorphic_types(type),
map_columns: {}
}
else
process_input_refs(refs)
end
columns =
polymorphic[:refs]
.first
.to_s
.classify
.constantize
.column_names
polymorphic[:refs].each do |p|
columns &= p.to_s.classify.constantize.column_names
end
polymorphic[:map_columns].values.each do |value|
columns += value.values
end
columns.uniq!
selectable_columns = {}
types = type.to_s.pluralize
polymorphic[:refs].each do |p|
map_columns = polymorphic[:map_columns][p] || {}
selectable_columns[p] = []
p.to_s.classify.constantize.column_names.each do |column_name|
if (alias_name = map_columns[column_name.to_sym]).present?
selectable_columns[p] <<
"#{types}.#{column_name} AS #{alias_name}"
elsif columns.index(column_name)
selectable_columns[p] <<
"#{types}.#{column_name}"
end
end
end
table = arel_table
joins_statements = polymorphic[:refs].map do |join_type|
join_table =
join_type.to_s.classify.constantize.arel_table.alias(types)
arel_table
.project(*(selectable_columns[join_type]))
.join(
join_table, Arel::Nodes::InnerJoin
)
.on(
table["#{type}_type".to_sym]
.eq(join_type.to_s.classify)
.and(
table["#{type}_id".to_sym].eq(join_table[:id])
)
)
end
polymorphic_union_scope(
type, polymorphic[:refs], *joins_statements
)
end
|