Permalink
Browse files

Initial commit.

  • Loading branch information...
tsmango committed Feb 28, 2009
0 parents commit 35e49c3eedc5dcb2c7c75f5e09e83634860516c7
Showing with 50 additions and 0 deletions.
  1. +17 −0 README
  2. +1 −0 init.rb
  3. +32 −0 lib/union.rb
17 README
@@ -0,0 +1,17 @@
+Plugin Details
+--------------
+This is an extremely naive 'railsification' of a SQL union.
+
+The first parameter, parts, is an array of hashes. Each hash is what you would normally send into a single find and represents each SELECT that will eventually be unioned together.
+
+The second paramter, options, is a hash of remaining options to be applied to the UNION of the parts (ie: order, limit, offset).
+
+A simple (and useless) example would be:
+User.union([{:conditions => ['name = ?', 'tom']}, {:conditions => ['name = ?', 'gary']}], {:order => 'created_at'})
+
+Essentially you can do any union, but it's up to you to make sure you don't pass the wrong stuff in because it's a pretty dumb implementation.
+
+Author
+------
+Thomas Mango
+http://slicedsoftware.com
@@ -0,0 +1 @@
+require 'union'
@@ -0,0 +1,32 @@
+class ActiveRecord::Base
+ class << self
+
+ # This simple implementation was extracted from
+ # ActiveRecord::Base .find, find_every and construct_finder_sql
+ def union(parts, options)
+ if parts.size >= 2
+ scope = scope(:find)
+
+ sql = '(' + parts.collect{|part| construct_finder_sql(optionate(part))}.join(') UNION (') + ') '
+ add_order!(sql, options[:order], scope)
+ add_limit!(sql, options, scope)
+
+ records = find_by_sql(sql)
+ records.each { |record| record.readonly! } if options[:readonly]
+ records
+ else
+ raise ArgumentError, 'There must be at least 2 parts to a union.'
+ end
+ end
+
+ private
+ # This was lifted from ActiveRecord::Base.find
+ def optionate(*args)
+ options = args.extract_options!
+ validate_find_options(options)
+ set_readonly_option!(options)
+
+ options
+ end
+ end
+end

0 comments on commit 35e49c3

Please sign in to comment.