Skip to content

Instantly share code, notes, and snippets.

@javiertoledo
Created September 7, 2012 03:40
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save javiertoledo/3662866 to your computer and use it in GitHub Desktop.
Save javiertoledo/3662866 to your computer and use it in GitHub Desktop.
Hack to allow unions on ActiveRecord models
Add union_hack.rb to your project, for example at lib folder and ensure you're loading it on your application.rb file:
# You'll need to add something like that
config.autoload_paths += %W(#{config.root}/lib)
Then extend your favourite model with the module and you'll be able to do unions with unique records, sorted by any fields and limited in number of records (see my_timeline_method):
class Profile < ActiveRecord::Base
extend UnionHack
has_many :events
has_many :friends
has_many :friend_events, :through => :friends, :source => :events
def my_timeline
Profile.union([events, friend_events], :distinct => true, :order => 'created_at DESC', :limit => 20)
end
end
module UnionHack
def union(relations, opts={})
query = 'SELECT '+ (opts[:distinct] ? 'DISTINCT ' : '' ) +'* FROM ((' + relations.map { |r| r.ast.to_sql }.join(') UNION (') + ')) AS t'
query << " ORDER BY #{opts[:order]}" if opts[:order]
query << " LIMIT #{opts[:limit]}" if opts[:limit]
find_by_sql(query)
end
end
@barockok
Copy link

what does 'ast' means on

relations.map { |r| r.ast.to_sql }

@kuboon
Copy link

kuboon commented Sep 25, 2012

ast is "Abstract Syntax Tree"

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