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?

I've created a gem that patches these operations into 
ActiveRecord::Relation 
(https://github.com/delonnewman/activerecord-setops), and tested it with 
Rails 5.  It's very little code:

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

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rubyonrails-core/e9721df1-09cd-4733-bfa2-33728189ea21%40googlegroups.com.

Reply via email to