Skip to content

Instantly share code, notes, and snippets.

@seguelador
Created September 8, 2017 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seguelador/494c4d5e989f42d8f4a91b3da2108216 to your computer and use it in GitHub Desktop.
Save seguelador/494c4d5e989f42d8f4a91b3da2108216 to your computer and use it in GitHub Desktop.
Active Record Union Scopes
# from https://stackoverflow.com/questions/6686920/activerecord-query-union
# lib/active_record_extension.rb
module ActiveRecordExtension
extend ActiveSupport::Concern
class_methods do
def union_scope(*scopes)
id_column = "#{table_name}.#{primary_key}"
sub_query = scopes.map { |s| s.select(id_column).to_sql }.join(" UNION ")
where "#{id_column} IN (#{sub_query})"
end
end
ActiveRecord::Base.send(:include, ActiveRecordExtension)
end
# from https://stackoverflow.com/questions/6686920/activerecord-query-union
# config/initializers/extensions.rb
require "active_record_extension"
# from https://stackoverflow.com/questions/6686920/activerecord-query-union
# example in some model
scope :active_nearby, -> { where(active: true).where('distance <= 25') }
scope :inactive_distant, -> { where(active: false).where('distance >= 200') }
scope :active_near_and_inactive_distant, -> { union_scope(active_nearby, inactive_distant) }
@dmitry
Copy link

dmitry commented Dec 17, 2019

Less problems and easier to follow:

    def union_scope(*scopes)
      scopes.inject(self) { |all, scope| all.or(where(id: scope)) }
    end

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