Skip to content

Instantly share code, notes, and snippets.

@coderifous
Created May 17, 2017 15:20
Show Gist options
  • Save coderifous/33e24f7e63800e169b03a16eb7eebb5b to your computer and use it in GitHub Desktop.
Save coderifous/33e24f7e63800e169b03a16eb7eebb5b to your computer and use it in GitHub Desktop.
# This unfortunate hack is necessary because ActiveRecord doesn't provide any
# way (clean or otherwise) to circumvent the default_scope when preloading.
#
# Here's a closed-but-unresolved issue that goes into it a bit more:
#
# https://github.com/rails/rails/issues/11036
#
# Example usage:
#
# In this scenario, Product and User may have paranoid deletes, and a
# default_scope of `where(deleted_at: nil)`, in which case the preloading
# queries may not find all associated records, and make your life a living
# hell.
#
# Wrapping the query in `disable_default_scopes` solves the problem by
# removing the default_scopes, running your block of code, and then
# restoring the default_scopes.
#
# disable_default_scopes(Product, User) {
# @orders = Order.preload(:product, :user).page(1).per(10)
#
# # Note: One "gotcha" is that, depending on your context, you will likely
# # need to force the actual loading of the data within the block.
# @orders.load
# }
#
module DefaultScopeCrutch
def disable_default_scopes(*klasses)
orig_scopes = {}
klasses.each do |klass|
klass.class_eval do
orig_scopes[klass] = default_scopes
self.default_scopes = []
end
end
retval = yield
klasses.each do |klass|
klass.class_eval do
self.default_scopes = orig_scopes[klass]
end
end
retval
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment