Hello all,
When dealing with legacy schemas or data models where the Active Record pattern is a bit of a stretch complex joins are often necessary. Many joins can be eliminated by using set operations on multiple queries.
Arel already supports set operations, and the Set module from the standard library already provide useful semantics.
Would this be something that could be of general use?
module ActiveRecord
class Relation
# Performs a set theoretic union works like `Array#+` but puts the load on the database
# and allows you to chain more relation operations.
def union(other)
binary_operation(Arel::Nodes::Union, other)
end
alias | union
alias + union
def union_all(other)
binary_operation(Arel::Nodes::UnionAll, other)
end
def intersect(other)
binary_operation(Arel::Nodes::Intersect, other)
end
alias & intersect
def except(other)
binary_operation(Arel::Nodes::Except, other)
end
alias difference except
alias - except
private
def binary_operation(op_class, other)
@klass.unscoped.from(Arel::Nodes::TableAlias.new(op_class.new(self.arel.ast, other.arel.ast), @klass.arel_table.name))
end
end
end
Thanks,
Delon Newman