Skip to content

Instantly share code, notes, and snippets.

@lsiden
Last active February 7, 2018 17:53
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save lsiden/260167a4d3574a580d97 to your computer and use it in GitHub Desktop.
Save lsiden/260167a4d3574a580d97 to your computer and use it in GitHub Desktop.
module ActiveRecord::UnionScope
#https://gist.github.com/tlowrimore/5162327
#http://stackoverflow.com/a/15413611/270511
module ActiveRecord::UnionScope
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def union_scope(*scopes)
id_column = "#{table_name}.id"
if (sub_query = scopes.reject { |sc| sc.count == 0 }.map { |s| s.select(id_column).to_sql }.join(" UNION ")).present?
where "#{id_column} IN (#{sub_query})"
else
none
end
end
end
end
@lsiden
Copy link
Author

lsiden commented Jul 21, 2014

This fixes a problem I encountered when I integrated https://gist.github.com/tlowrimore/5162327 into my RoR app. The problem happens when one of the scopes returns no values. Apparently, to_sql() is able to evaluate when a query will return nothing and it returns an empty string. So the final query begins " UNION SELECT ... " which is invalid SQL of course.

There are other ways to fix this, like checking for /^ UNION / and prepending "select 1 where 1=0". The main thing is that anyone using https://gist.github.com/tlowrimore/5162327 this has to be aware of the problem.

@lsiden
Copy link
Author

lsiden commented Jul 24, 2014

Just fixed this by counting the scopes that actually return something. The previous way failed sometimes.

@lsiden
Copy link
Author

lsiden commented Jul 25, 2014

Even better!

@abdul-shajin
Copy link

If my scopes accept arguments, will it work ??

@bogdanRada
Copy link

this is correct but needs just small change:

This code:

 map { |s| s.select(id_column).to_sql }

should be replaced with this:

.map { |s|   "(#{s.select(id_column).to_sql})" }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment