summaryrefslogtreecommitdiff
path: root/app/models/concerns/sortable.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/concerns/sortable.rb')
-rw-r--r--app/models/concerns/sortable.rb23
1 files changed, 23 insertions, 0 deletions
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index a155a064032..fdacfa5a194 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -5,6 +5,25 @@
module Sortable
extend ActiveSupport::Concern
+ module DropDefaultScopeOnFinders
+ # Override these methods to drop the `ORDER BY id DESC` default scope.
+ # See http://dba.stackexchange.com/a/110919 for why we do this.
+ %i[find find_by find_by!].each do |meth|
+ define_method meth do |*args, &block|
+ return super(*args, &block) if block
+
+ unordered_relation = unscope(:order)
+
+ # We cannot simply call `meth` on `unscope(:order)`, since that is also
+ # an instance of the same relation class this module is included into,
+ # which means we'd get infinite recursion.
+ # We explicitly use the original implementation to prevent this.
+ original_impl = method(__method__).super_method.unbind
+ original_impl.bind(unordered_relation).call(*args)
+ end
+ end
+ end
+
included do
# By default all models should be ordered
# by created_at field starting from newest
@@ -18,6 +37,10 @@ module Sortable
scope :order_updated_asc, -> { reorder(updated_at: :asc) }
scope :order_name_asc, -> { reorder(name: :asc) }
scope :order_name_desc, -> { reorder(name: :desc) }
+
+ # All queries (relations) on this model are instances of this `relation_klass`.
+ relation_klass = relation_delegate_class(ActiveRecord::Relation)
+ relation_klass.prepend DropDefaultScopeOnFinders
end
module ClassMethods