Commit e01dd08e authored by Alex Kalderimis's avatar Alex Kalderimis

Deal with model exclusions correctly

This involves custom handling for polymorphic models, and null-safety.
parent bd0e3267
......@@ -74,7 +74,7 @@ module RelativePositioning
end
def relative_siblings(relation = scoped_items)
object.relative_siblings(relation)
object.exclude_self(relation)
end
# Handles the possibility that the position is already occupied by a sibling
......@@ -114,7 +114,7 @@ module RelativePositioning
def scoped_items
r = model_class.relative_positioning_query_base(object)
r = r.id_not_in(ignoring.id) if ignoring.present?
r = object.exclude_self(r, excluded: ignoring) if ignoring.present?
r
end
......@@ -597,9 +597,9 @@ module RelativePositioning
.update_all("relative_position = relative_position + #{delta}")
end
# This method is used to exclude the current self from a relation. Customize
# this if `id <> :id` is not sufficient
def relative_siblings(relation)
relation.id_not_in(id)
# This method is used to exclude the current self (or another object)
# from a relation. Customize this if `id <> :id` is not sufficient
def exclude_self(relation, excluded: self)
relation.id_not_in(excluded.id)
end
end
......@@ -34,9 +34,13 @@ module EpicTreeSorting
end
end
override :relative_siblings
def relative_siblings(relation)
relation.where.not('object_type = ? AND id = ?', self.class.table_name.singularize, self.id)
override :exclude_self
def exclude_self(relation, excluded: self)
return relation unless excluded&.id.present?
object_type = excluded.try(:object_type) || excluded.class.table_name.singularize
relation.where.not('object_type = ? AND id = ?', object_type, excluded.id)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment