module Resort::Sortable::InstanceMethods
Instance methods to use.
Public Instance Methods
append_to(another)
click to toggle source
Puts the object right after another object in the list.
# File lib/resort.rb, line 175 def append_to(another) self.class.transaction do self.lock! return if another.next_id == id another.lock! delete_from_list if self.next_id or (another && another.next_id) raise(ActiveRecord::RecordNotSaved) unless self.update_attribute(:next_id, another.next_id) end if another raise(ActiveRecord::RecordNotSaved) unless another.update_attribute(:next_id, self.id) end end end
include_in_list!()
click to toggle source
Includes the object in the linked list.
If there are no other objects, it prepends the object so that it is in the first position. Otherwise, it appends it to the end of the empty list.
# File lib/resort.rb, line 143 def include_in_list! self.class.transaction do self.lock! _siblings.count > 0 ? last!\ : prepend end end
prepend()
click to toggle source
Puts the object in the first position of the list.
# File lib/resort.rb, line 152 def prepend self.class.transaction do self.lock! return if first? if _siblings.count > 0 delete_from_list old_first = _siblings.first_in_order raise(ActiveRecord::RecordNotSaved) unless self.update_attribute(:next_id, old_first.id) raise(ActiveRecord::RecordNotSaved) unless old_first.update_attribute(:first, false) end raise(ActiveRecord::RecordNotSaved) unless self.update_attribute(:first, true) end end
push()
click to toggle source
Puts the object in the last position of the list.
# File lib/resort.rb, line 167 def push self.class.transaction do self.lock! self.append_to(_siblings.last_in_order) unless last? end end
siblings()
click to toggle source
Default definition of siblings, i.e. every instance of the model.
Can be overriden to specify a different scope for the siblings. For example, if we wanted to limit a products tree inside a ProductLine scope, we would do the following:
class Product < ActiveRecord::Base belongs_to :product_line resort! def siblings self.product_line.products end
This way, every product line is an independent tree of sortable products.
@return [ActiveRecord::Relation] the element’s siblings relation.
# File lib/resort.rb, line 135 def siblings self.class.scoped end
Private Instance Methods
_siblings()
click to toggle source
# File lib/resort.rb, line 220 def _siblings table = self.class.arel_table siblings.where(table[:id].not_eq(self.id)) end
delete_from_list()
click to toggle source
# File lib/resort.rb, line 192 def delete_from_list if first? && self.next self.next.lock! raise(ActiveRecord::RecordNotSaved) unless self.next.update_attribute(:first, true) elsif self.previous self.previous.lock! p = self.previous self.previous = nil unless frozen? raise(ActiveRecord::RecordNotSaved) unless p.update_attribute(:next_id, self.next_id) end unless frozen? self.first = false self.next = nil save! end end
last!()
click to toggle source
# File lib/resort.rb, line 213 def last! self.class.transaction do self.lock! raise(ActiveRecord::RecordNotSaved) unless _siblings.last_in_order.update_attribute(:next_id, self.id) end end
last?()
click to toggle source
# File lib/resort.rb, line 209 def last? !self.first && !self.next_id end